<template>
    <div
        class="page_root"
        :key="queryUpdateFlag"
        data-page-name="水泥配料里程碑进度表"
        data-page-identification="v_6w477pgdzt"
    >
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip">
            <!-- begin vid_01q526lihn 自定义模板_oo6ulgwhjy -->
            <!--            加号进展-->
            <a-modal
                :visible="progressState.visible"
                title="新建进展"
                centered
                @ok="confirmProgress"
                @cancel="cancelProgress"
                width="1200px"
                :mask-closable="false"
                :keyboard="false"
            >
                <a-form-item label="进展">
                    <a-textarea v-model:value="progressState.data" :rows="12" />
                </a-form-item>
            </a-modal>
            <!--            加号进展-->
            <!--            问题风险改造-->
            <a-modal
                width="100%"
                :visible="planState.questionVisible"
                :title="planState.questionTitle"
                centered
                @cancel="cancelQuestion"
                :footer="null"
                :body-style="{
                    paddingTop: '0'
                }"
                :mask-closable="false"
                :keyboard="false"
            >
                <Question
                    v-if="planState.questionVisible"
                    :id="planState.questionId"
                    :from="planState.from"
                    :projectId="planState.projectId"
                />
            </a-modal>
            <!--            问题风险改造-->
            <!--            计划调整-->
            <a-modal
                width="100%"
                v-if="planState.planChangeVisible"
                :visible="planState.planChangeVisible"
                :title="planState.planChangeTitle"
                centered
                :footer="null"
                :mask-closable="false"
                :keyboard="false"
                @cancel="cancelPlanChange"
                :body-style="{
                    maxHeight: '800px',
                    overflowY: 'auto'
                }"
                destroy-on-close
            >
                <PlanChange
                    :id="planState.planChangeId"
                    :type="planState.type"
                    :from="planState.from"
                    :projectId="planState.projectId"
                />
            </a-modal>
            <!--            计划调整-->
            <!--            调整记录-->
            <a-modal
                width="100%"
                v-if="planState.showChangeVisible"
                :visible="planState.showChangeVisible"
                :title="planState.showChangeTitle"
                centered
                :mask-closable="false"
                :keyboard="false"
                @cancel="cancelShowChange"
                :footer="null"
            >
                <PlanChange
                    :id="planState.showChangeId"
                    :type="planState.type"
                    :from="planState.from"
                    :projectId="planState.projectId"
                />
            </a-modal>
            <!--            调整记录--->
            <!--          新增问题-->
            <a-modal
                :visible="lhwtState.addOrEditVisible"
                :title="lhwtState.modalTitle"
                @ok="confirmLhwt"
                @cancel="cancelLhwt"
                centered
                destroy-on-close
                :ok-button-props="{ loading: lhwtState.okLoading }"
                width="800px"
                :mask-closable="false"
                :keyboard="false"
            >
                <a-form :model="lhwtState.changeForm" ref="lhwtRef">
                    <div class="meeting-div">
                        <a-row>
                            <a-col :span="12">
                                <a-form-item
                                    label="日期"
                                    :rules="[{ required: false, message: '请选择日期', trigger: 'blur' }]"
                                    name="meetingDate"
                                >
                                    <a-date-picker
                                        :valueFormat="'YYYY-MM-DD'"
                                        style="width: 100%"
                                        v-model:value="lhwtState.changeForm.meetingDate"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="区域"
                                    :rules="[{ required: false, message: '请选择区域', trigger: 'blur' }]"
                                    name="areaCode"
                                >
                                    <a-select
                                        allow-clear
                                        show-search
                                        v-model:value="lhwtState.changeForm.areaCode"
                                        :options="lhwtState.areaNameList"
                                        placeholder="请选择"
                                        :field-names="{ label: 'label', value: 'value' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        @change="areaChange"
                                        :max-tag-count="2"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="工厂名称"
                                    :rules="[{ required: false, message: '请选择工厂', trigger: 'blur' }]"
                                    name="projectId"
                                >
                                    <a-select
                                        allow-clear
                                        show-search
                                        v-model:value="lhwtState.changeForm.projectId"
                                        :options="lhwtState.projectList"
                                        placeholder="请选择"
                                        :field-names="{ label: 'label', value: 'value' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        @change="factoryChange"
                                        @focus="getFactory"
                                        :max-tag-count="2"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="项目总监"
                                    :rules="[{ required: false, message: '请选择项目总监', trigger: 'blur' }]"
                                    name="projectDirector"
                                >
                                    <a-select
                                        allow-clear
                                        show-search
                                        v-model:value="lhwtState.changeForm.projectDirector"
                                        :options="lhwtState.allUser"
                                        placeholder="请选择"
                                        :field-names="{ label: 'name', value: 'name' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="项目经理"
                                    :rules="[{ required: false, message: '请选择经理', trigger: 'blur' }]"
                                    name="pmName"
                                >
                                    <a-select
                                        allow-clear
                                        show-search
                                        v-model:value="lhwtState.changeForm.pmName"
                                        :options="lhwtState.allUser"
                                        placeholder="请选择"
                                        :field-names="{ label: 'name', value: 'name' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="风险类型"
                                    :rules="[{ required: false, message: '请选择风险类型', trigger: 'blur' }]"
                                    name="riskType"
                                >
                                    <a-select
                                        allow-clear
                                        show-search
                                        v-model:value="lhwtState.changeForm.riskType"
                                        :options="lhwtState.fxlxList"
                                        placeholder="请选择"
                                        :field-names="{ label: 'itemName', value: 'itemName' }"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item label="会议来源">
                                    <a-select
                                        allow-clear
                                        mode="multiple"
                                        show-search
                                        v-model:value="lhwtState.changeForm.meetingSourceList"
                                        :options="state.hylyList"
                                        placeholder="请选择"
                                        :field-names="{ label: 'itemName', value: 'itemName' }"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item
                                    label="问题&风险描述"
                                    :rules="[{ required: false, message: '请输入问题&风险描述', trigger: 'blur' }]"
                                    name="questionDescription"
                                >
                                    <a-textarea v-model:value="lhwtState.changeForm.questionDescription" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item
                                    label="解决方案及行动项"
                                    :rules="[{ required: false, message: '请输入解决方案及行动项', trigger: 'blur' }]"
                                    name="solutionOrAction"
                                >
                                    <a-textarea v-model:value="lhwtState.changeForm.solutionOrAction" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="责任人"
                                    :rules="[{ required: false, message: '请选择责任人', trigger: 'blur' }]"
                                    name="responsiblePersonList"
                                >
                                    <a-select
                                        allow-clear
                                        show-search
                                        v-model:value="lhwtState.changeForm.responsiblePersonList"
                                        :options="state.allUser"
                                        placeholder="请选择"
                                        mode="multiple"
                                        :max-tag-count="2"
                                        :field-names="{ label: 'name', value: 'name' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="计划完成时间"
                                    :rules="[{ required: false, message: '请选择计划完成时间', trigger: 'blur' }]"
                                    name="endTime"
                                >
                                    <a-date-picker
                                        :valueFormat="'YYYY-MM-DD'"
                                        style="width: 100%"
                                        v-model:value="lhwtState.changeForm.endTime"
                                        placeholder="请选择计划完成时间"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="完成状态"
                                    :rules="[
                                        {
                                            required: false,
                                            message: '请选择完成状态',
                                            trigger: 'blur'
                                        }
                                    ]"
                                    name="finishStatus"
                                >
                                    <a-select
                                        allow-clear
                                        placeholder="请选择"
                                        :options="[
                                            {
                                                label: '未启动',
                                                value: '未启动'
                                            },
                                            {
                                                label: '处理中',
                                                value: '处理中'
                                            },
                                            {
                                                label: '已完成',
                                                value: '已完成'
                                            }
                                        ]"
                                        v-model:value="lhwtState.changeForm.finishStatus"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </div>
                </a-form>
            </a-modal>
            <!--          新增问题-->
            <!--          编辑信息统计-->
            <a-modal
                :visible="statisticsState.editStatisticsVisible"
                title="编辑信息统计"
                width="1000px"
                centered
                @cancel="cancelEditStatistics"
                @ok="confirmEditStatistics"
                :ok-button-props="{ loading: statisticsState.editLoading }"
                :body-style="{
                    paddingBottom: 0
                }"
                :mask-closable="false"
                :keyboard="false"
            >
                <div class="edit-field-form">
                    <a-form :model="statisticsState.editForm" ref="editStatisticsRef" layout="vertical">
                        <a-row>
                            <a-col :span="12">
                                <a-form-item label="区域/项目">
                                    <div style="width: 100%">{{ statisticsState.editForm.projectIdList }}</div>
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="计划结束时间">
                                    <div style="width: 100%">{{ statisticsState.editForm.planEndTime }}</div>
                                </a-form-item>
                            </a-col>
                            <a-col :span="24">
                                <a-form-item
                                    :label="currentNewField.label"
                                    :rules="{
                                        required: true,
                                        message: `请完善${currentNewField.label}`,
                                        trigger: 'blur'
                                    }"
                                    name="value"
                                >
                                    <template
                                        v-if="
                                            currentNewField.fieldType === 'SELECT' &&
                                            currentNewField.selectType === 'CHECK'
                                        "
                                    >
                                        <a-select
                                            style="width: 100%"
                                            mode="multiple"
                                            :options="currentNewField.selectList"
                                            v-model:value="statisticsState.editForm.value"
                                        />
                                    </template>
                                    <template
                                        v-if="
                                            currentNewField.fieldType === 'SELECT' &&
                                            currentNewField.selectType === 'RADIO'
                                        "
                                    >
                                        <a-select
                                            style="width: 100%"
                                            :options="currentNewField.selectList"
                                            v-model:value="statisticsState.editForm.value"
                                        />
                                    </template>
                                    <template v-if="currentNewField.fieldType === 'SIMPLE_INPUT'">
                                        <a-input
                                            v-model:value="statisticsState.editForm.value"
                                            :maxlength="currentNewField.inputLimit"
                                            show-count
                                        />
                                    </template>
                                    <template v-if="currentNewField.fieldType === 'DATE'">
                                        <a-date-picker
                                            style="width: 100%"
                                            :getPopupContainer="getPopupContainer"
                                            v-model:value="statisticsState.editForm.value"
                                            value-format="YYYY-MM-DD"
                                        />
                                    </template>
                                    <template v-if="currentNewField.fieldType === 'FILE'">
                                        <a-upload
                                            v-model:file-list="statisticsState.editForm.value"
                                            :multiple="true"
                                            :before-upload="handlerResolvedUpload"
                                            @remove="handlerResolvedRemove"
                                            accept=".xlsx, image/*,.docx,, .xls,.mp4"
                                        >
                                            <a-button type="primary">
                                                <upload-outlined />
                                                上传
                                            </a-button>
                                        </a-upload>
                                    </template>
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </a-form>
                </div>
            </a-modal>
            <!--          编辑信息统计-->
            <!--          新建进展-->
            <a-modal
                :visible="state.addJzVisible"
                centered
                title="新建进展"
                @ok="handleAddJz"
                @cancel="cancelJz"
                :mask-closable="false"
                width="1200px"
                :keyboard="false"
            >
                <div style="position: relative">
                    <a-textarea :rows="12" v-model:value="state.jzContent" />
                    <div style="position: absolute; right: 0">上下拖拽调整高度</div>
                </div>
            </a-modal>
            <!--          新建进展-->
            <!--          编辑进展-->
            <a-modal
                :visible="state.editJzVisible"
                centered
                width="1200px"
                title="编辑最新进展"
                @ok="handleConfirmEditJz"
                @cancel="cancelEditJz"
                :mask-closable="false"
                :keyboard="false"
            >
                <div style="position: relative">
                    <a-textarea :rows="12" v-model:value="state.editJzContent" />
                    <div style="position: absolute; right: 0">上下拖拽调整高度</div>
                </div>
            </a-modal>
            <!--          编辑进展-->
            <!--          显示设置-->
            <a-modal
                :visible="state.settingVisible"
                title="显示设置"
                centered
                width="700px"
                @ok="confirmSetting"
                @cancel="state.settingVisible = false"
                :ok-button-props="{
                    loading: statisticsState.settingLoading
                }"
                :body-style="{
                    paddingTop: '0'
                }"
                :mask-closable="false"
                :keyboard="false"
            >
                <a-tabs v-model:activeKey="state.activeKey">
                    <a-tab-pane key="基础信息" tab="基础信息" />
                    <a-tab-pane key="项目阶段" tab="项目阶段" />
                    <a-tab-pane key="时间" tab="时间" />
                    <a-tab-pane key="其他" tab="其他" />
                    <a-tab-pane key="信息统计" tab="信息统计" />
                </a-tabs>
                <div v-if="state.activeKey === '时间'">
                    <a-checkbox v-model:checked="state.timeAllCheck" @change="timeAllChange">全选</a-checkbox>
                    <a-checkbox-group
                        @change="handleTimeCheckChange"
                        v-model:value="state.checkList"
                        style="width: 100%"
                    >
                        <a-row>
                            <a-col :span="6">
                                <a-checkbox value="计划开始">计划开始时间</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="计划结束">计划结束时间</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="实际开始">实际开始时间</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="实际结束">实际结束时间</a-checkbox>
                            </a-col>
                        </a-row>
                        <a-row>
                            <a-col :span="6"> <a-checkbox value="预计开始">预计开始时间</a-checkbox> </a-col
                            ><a-col :span="6">
                                <a-checkbox value="预计结束">预计结束时间</a-checkbox>
                            </a-col>
                        </a-row>
                    </a-checkbox-group>
                </div>
                <div v-if="state.activeKey === '信息统计'">
                    <a-transfer
                        :titles="['隐藏', '展示']"
                        v-model:target-keys="statisticsState.targetKeys"
                        v-model:selected-keys="statisticsState.selectedKeys"
                        :data-source="statisticsState.mockData"
                        :list-style="{
                            width: '300px',
                            height: '500px'
                        }"
                        :render="item => item.chinessName"
                    />
                </div>
                <div v-if="state.activeKey === '基础信息'">
                    <a-checkbox v-model:checked="state.baseAllCheck" @change="baseAllChange">全选</a-checkbox>
                    <a-checkbox-group
                        @change="handleBaseCheckChange"
                        v-model:value="state.baseCheckList"
                        style="width: 100%"
                    >
                        <a-row>
                            <a-col :span="6">
                                <a-checkbox value="批次">批次</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="项目总监">项目总监</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="水泥专家">水泥专家</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="项目经理">项目经理</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="熟料算法">熟料算法</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="水泥算法">水泥算法</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="客成经理">客成经理</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="客户满意工程师">客户满意工程师</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="PMO">PMO</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="项目阶段">项目阶段</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="项目状态">项目状态</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="转售后">转售后</a-checkbox>
                            </a-col>
                        </a-row>
                    </a-checkbox-group>
                </div>
                <div v-if="state.activeKey === '其他'">
                    <a-checkbox v-model:checked="state.otherAllCheck" @change="otherAllChange">全选</a-checkbox>
                    <a-checkbox-group
                        @change="handleOtherCheckChange"
                        v-model:value="state.otherCheckList"
                        style="width: 100%"
                    >
                        <a-row>
                            <a-col :span="6">
                                <a-checkbox value="进展">进展</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="问题风险">问题风险</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="风险等级">风险等级</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="项目支持">项目支持</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="正式运行持续天数">正式运行持续天数</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="综合样20次">综合样20次</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="降本空间">降本空间</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="生产计划">生产计划</a-checkbox>
                            </a-col>
                            <a-col :span="6">
                                <a-checkbox value="客情关系">客情关系</a-checkbox>
                            </a-col>
                        </a-row>
                    </a-checkbox-group>
                </div>
                <div v-if="state.activeKey === '项目阶段'">
                    <a-checkbox v-model:checked="state.mileAllCheck" @change="mileAllChange">全选</a-checkbox>
                    <a-checkbox-group
                        @change="handleMileCheckChange"
                        v-model:value="state.milepostCheckList"
                        style="width: 100%"
                    >
                        <a-row>
                            <a-col :span="6" v-for="(item, index) in state.allmileOptions">
                                <a-checkbox :value="item">{{ item }}</a-checkbox>
                            </a-col>
                        </a-row>
                    </a-checkbox-group>
                </div>
            </a-modal>
            <!--          显示设置-->
            <!--      编辑状态-->
            <a-drawer
                :visible="state.editStatusVisible"
                placement="right"
                @ok="confirmItemStatus"
                @close="cancelItem"
                width="80%"
                :mask-closable="false"
                :getContainer="getPopupContainer"
                :body-style="{
                    paddingBottom: 0,
                    paddingTop: 0
                }"
                :footerStyle="{
                    boxShadow: '0 0 5px 0 rgba(0,0,0,0.20)'
                }"
                :closable="false"
            >
                <template #title>
                    <div class="draw-title">
                        {{ state.modalTitle }}
                    </div>
                </template>
                <template #footer>
                    <div class="footer">
                        <a-space style="display: flex; justify-content: end">
                            <a-button type="primary" ghost @click="cancelItem">取消</a-button>
                            <a-button type="primary" @click="confirmItemStatus" :loading="state.changeLoading"
                                >保存</a-button
                            >
                            <a-button type="primary" @click="confirmItemAndOpenNext" :loading="state.changeIndexLoading"
                                >保存并打开下一条</a-button
                            >
                        </a-space>
                    </div>
                </template>
                <div class="my-page">
                    <a-tabs v-model:active-key="state.changeActivekey">
                        <a-tab-pane key="基本信息" tab="基本信息" />
                        <a-tab-pane key="时间维护" tab="时间维护" />
                    </a-tabs>
                    <a-form :model="state.changeForm" ref="changeFormRef">
                        <div v-if="state.changeActivekey === '基本信息'">
                            <a-row>
                                <a-col :span="8">
                                    <a-form-item label="里程碑阶段">
                                        <a-select
                                            :disabled="getDisabledStatus()"
                                            allow-clear
                                            placeholder="请选择"
                                            :options="state.milepostList"
                                            v-model:value="state.changeForm.milepostName"
                                            :field-names="{ label: 'stageName', value: 'stageName' }"
                                            :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.stageName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="8">
                                    <a-form-item label="项目状态">
                                        <a-select
                                            :disabled="getDisabledStatus()"
                                            allow-clear
                                            placeholder="请选择"
                                            :field-names="{ label: 'itemName', value: 'itemName' }"
                                            :options="state.statusList"
                                            v-model:value="state.changeForm.projectStatus"
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>

                                <a-col :span="8" style="pointer-events: none">
                                    <a-form-item label="正式运行天数">
                                        <a-input
                                            :disabled="getDisabledStatus()"
                                            v-model:value="state.changeForm.runDays"
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>

                            <!--                          新-->
                            <a-row>
                                <a-col :span="8">
                                    <a-form-item label="风险等级">
                                        <a-select
                                            :disabled="getDisabledStatus()"
                                            allow-clear
                                            placeholder="请选择"
                                            :options="state.fxdjList"
                                            :field-names="{ label: 'itemName', value: 'itemName' }"
                                            v-model:value="state.changeForm.riskLevel"
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>

                                <a-col :span="8">
                                    <a-form-item label="综合样20次">
                                        <a-select
                                            :disabled="getDisabledStatus()"
                                            allow-clear
                                            placeholder="请选择"
                                            :options="state.zhyList"
                                            :field-names="{ label: 'itemName', value: 'itemName' }"
                                            v-model:value="state.changeForm.comprehensiveSample"
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="8">
                                    <a-form-item label="降本空间">
                                        <a-input
                                            :disabled="getDisabledStatus()"
                                            v-model:value="state.changeForm.expectedCostReduction"
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>

                            <!--                          新-->
                            <div class="jz-body">
                                <div class="bottom-title">
                                    <div class="title-left"><div class="jz-img"></div>进展</div>
                                    <a-space>
                                        <a-button type="primary" @click="state.addJzVisible = true">新建</a-button>
                                        <a-button type="primary" @click="toggleExpand">
                                            {{ isExpanded ? '只看最新' : '查看历史' }}
                                        </a-button>
                                    </a-space>
                                </div>

                                <div class="jz-form">
                                    <div
                                        class="jz-item"
                                        v-for="(item, index) in state.changeForm.projectProgressDetailList"
                                        :key="item.id"
                                        v-show="isExpanded || index < 1"
                                    >
                                        <div class="title-tip">
                                            <div v-if="item.createdTime">
                                                <span class="title-key">添加时间：</span>
                                                <span class="title-value">{{ item.createdTime }}</span>
                                            </div>
                                            <div v-if="item.createdBy">
                                                <span class="title-key">添加人：</span>
                                                <span class="title-value">{{ item.createdBy }}</span>
                                            </div>
                                            <div v-if="index == 0" style="position: relative; top: -5px">
                                                <span class="title-key"></span>
                                                <span class="title-value">
                                                    <a-button
                                                        type="link"
                                                        :disabled="!isToday(item.createdTime || item.testTime)"
                                                        @click="handleEditJz(item)"
                                                    >
                                                        编辑</a-button
                                                    >
                                                </span>
                                            </div>
                                            <div>
                                                <a-button
                                                    style="position: relative; top: -5px"
                                                    v-if="item.deleteFlag"
                                                    type="link"
                                                    @click="handleDeleteJz(item, index)"
                                                >
                                                    删除</a-button
                                                >
                                            </div>
                                        </div>
                                        <div class="jz-content" v-if="item.progress">
                                            <!--                                            <div v-for="(item, index) in handlerGetSpace(item.progress)">{{-->
                                            <!--                                                item-->
                                            <!--                                            }}</div>-->
                                            <div style="white-space: pre-wrap; word-break: break-word">{{
                                                item.progress
                                            }}</div>
                                        </div>
                                        <!--                                      <a-textarea v-model:value="item.progress"></a-textarea>-->
                                    </div>
                                </div>
                            </div>
                            <div class="wt-body">
                                <div class="bottom-title">
                                    <div class="title-left"> <div class="wt-img"></div>问题&风险</div>
                                    <!--                                    <a-button @click="handleAddQuestion" type="primary">新建</a-button>-->
                                </div>
                                <Question
                                    ref="questionRef"
                                    v-if="state.editStatusVisible"
                                    :id="planState.questionId"
                                    :from="planState.from"
                                    :projectId="planState.projectId"
                                />
                            </div>
                            <div class="bottom-form">
                                <a-col :span="24">
                                    <a-form-item label="项目支持">
                                        <a-textarea
                                            :disabled="getDisabledStatus()"
                                            v-model:value="state.changeForm.supportors"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="24">
                                    <a-form-item label="生产计划">
                                        <a-textarea
                                            :disabled="getDisabledStatus()"
                                            v-model:value="state.changeForm.productionPlan"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="24">
                                    <a-form-item label="客情关系">
                                        <a-textarea
                                            :disabled="getDisabledStatus('commercial')"
                                            v-model:value="state.changeForm.customerRelationship"
                                        />
                                    </a-form-item>
                                </a-col>
                            </div>
                        </div>
                        <div v-else>
                            <a-row
                                :gutter="24"
                                v-for="stage in state.changeForm.projectProgressStageList"
                                :key="stage.id || stage.stageName"
                            >
                                <a-col :span="24">
                                    <div class="time-title">
                                        <div class="title-left">
                                            <div class="stage-icon"></div>
                                            {{ stage.stageName }}
                                        </div>
                                    </div>
                                </a-col>
                                <a-col :span="12" class="col-height" v-for="time in timesMap" :key="time.field">
                                    <a-form-item
                                        :label="time.label + '时间'"
                                        :class="{ 'expect-overdue': isExpectOverdue(time, stage) }"
                                    >
                                        <a-date-picker
                                            :disabled="getDisabledState(time, stage)"
                                            style="width: 100%"
                                            v-model:value="stage[time.field]"
                                            value-format="YYYY-MM-DD"
                                            @change="timeChange(time, stage)"
                                        />
                                    </a-form-item>
                                </a-col>
                            </a-row>
                        </div>
                    </a-form>
                </div>
            </a-drawer>
            <!--      编辑状态-->
            <!--新建信息统计-->
            <a-modal
                :visible="statisticsState.statisticsVisible"
                title="新建信息统计"
                width="800px"
                centered
                :body-style="{
                    paddingBottom: '0px'
                }"
                destroy-on-close
                @cancel="cancelStatistics"
                @ok="confirmStatistics"
                :ok-button-props="{ loading: statisticsState.addLoading }"
                :mask-closable="false"
                :keyboard="false"
            >
                <a-form :model="statisticsState.statisticsForm" ref="statisticsRef">
                    <div class="statistics-div">
                        <a-row>
                            <a-col :span="12">
                                <a-form-item
                                    label="区域/项目"
                                    :rules="[{ required: true, message: '请选择区域/项目', trigger: 'blur' }]"
                                    name="projectIdList"
                                >
                                    <a-tree-select
                                        v-model:value="statisticsState.statisticsForm.projectIdList"
                                        multiple
                                        treeCheckable
                                        style="width: 100%"
                                        placeholder="请选择"
                                        allow-clear
                                        :tree-data="statisticsState.treeData"
                                        :fieldNames="{
                                            children: 'children',
                                            label: 'nodeName',
                                            value: 'id'
                                        }"
                                        tree-node-filter-prop="label"
                                        :max-tag-count="1"
                                        @focus="getTreeData"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item
                                    label="计划完成时间"
                                    :rules="[{ required: true, message: '请选择计划完成时间', trigger: 'blur' }]"
                                    name="planEndTime"
                                >
                                    <a-date-picker
                                        style="width: 100%"
                                        v-model:value="statisticsState.statisticsForm.planEndTime"
                                        value-format="YYYY-MM-DD"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row>
                            <a-col :span="24">
                                <a-form-item
                                    label="填写角色"
                                    :rules="[{ required: true, message: '请选择填写角色', trigger: 'blur' }]"
                                    name="role"
                                >
                                    <a-radio-group v-model:value="statisticsState.statisticsForm.role">
                                        <a-radio value="DIRECTOR">项目总监</a-radio>
                                        <a-radio value="PM">项目经理</a-radio>
                                        <a-radio value="PMO">PMO</a-radio>
                                    </a-radio-group>
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-divider style="height: 1px; background-color: #3875ff; margin: 0; margin-bottom: 16px" />
                        <div
                            class="componment-item"
                            v-for="(item, index) in statisticsState.statisticsForm.componentList"
                            :key="index"
                        >
                            <a-row :gutter="24">
                                <a-col :span="18">
                                    <a-form-item
                                        label="字段名称"
                                        :rules="[{ required: true, message: '请输入字段名称', trigger: 'blur' }]"
                                        :name="['componentList', index, 'lableName']"
                                    >
                                        <a-input
                                            v-model:value="
                                                statisticsState.statisticsForm.componentList[index].lableName
                                            "
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6" style="display: flex; justify-content: end; align-items: start">
                                    <a-space>
                                        <a-button
                                            type="primary"
                                            v-if="index == statisticsState.statisticsForm.componentList.length - 1"
                                            ghost
                                            @click="handleAddField"
                                            >新增</a-button
                                        >
                                        <a-button type="primary" ghost @click="handleDeleteField(index)">删除</a-button>
                                    </a-space>
                                </a-col>
                            </a-row>
                            <a-form-item
                                label="组件类型"
                                :rules="[{ required: true, message: '请选择组件类型', trigger: 'blur' }]"
                                :name="['componentList', index, 'componentType']"
                            >
                                <a-radio-group
                                    v-model:value="statisticsState.statisticsForm.componentList[index].componentType"
                                    @change="changeComponentType(index)"
                                >
                                    <a-radio value="SELECT">选择</a-radio>
                                    <a-radio value="SIMPLE_INPUT">输入</a-radio>
                                    <a-radio value="DATE">时间</a-radio>
                                    <a-radio value="FILE">图片附件</a-radio>
                                </a-radio-group>
                            </a-form-item>
                            <div
                                class="statisics-form-content"
                                v-if="
                                    statisticsState.statisticsForm.componentList[index].componentType &&
                                    statisticsState.statisticsForm.componentList[index].componentType !== 'FILE' &&
                                    statisticsState.statisticsForm.componentList[index].componentType !== 'DATE'
                                "
                            >
                                <div
                                    v-if="
                                        statisticsState.statisticsForm.componentList[index].componentType === 'SELECT'
                                    "
                                >
                                    <a-form-item
                                        label="选择框类型"
                                        :rules="[{ required: true, message: '请选择选择框类型', trigger: 'blur' }]"
                                        :name="['componentList', index, 'selectType']"
                                    >
                                        <a-radio-group
                                            v-model:value="
                                                statisticsState.statisticsForm.componentList[index].selectType
                                            "
                                        >
                                            <a-radio value="RADIO">单选</a-radio>
                                            <a-radio value="CHECK">多选</a-radio>
                                        </a-radio-group>
                                    </a-form-item>
                                    <div
                                        class="select-list"
                                        v-for="(select, selectIndex) in statisticsState.statisticsForm.componentList[
                                            index
                                        ].selectList"
                                    >
                                        <div class="form-content-select">
                                            <a-form-item
                                                label="选项"
                                                :rules="[{ required: true, message: '请输入选项', trigger: 'blur' }]"
                                                :name="['componentList', index, 'selectList', selectIndex, 'value']"
                                            >
                                                <a-input
                                                    v-model:value="
                                                        statisticsState.statisticsForm.componentList[index].selectList[
                                                            selectIndex
                                                        ].value
                                                    "
                                                />
                                            </a-form-item>
                                            <div class="select-btn">
                                                <a-space>
                                                    <a-button
                                                        type="link"
                                                        ghost
                                                        @click="handleAddSelect(index, selectIndex)"
                                                        >下方插入</a-button
                                                    >
                                                    <a-button
                                                        type="link"
                                                        @click="handleDeleteSelect(index, selectIndex)"
                                                        >删除</a-button
                                                    >
                                                </a-space>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div
                                    v-if="
                                        statisticsState.statisticsForm.componentList[index].componentType ===
                                        'SIMPLE_INPUT'
                                    "
                                >
                                    <a-form-item
                                        label="字数限制"
                                        :rules="[{ required: true, message: '请输入字数限制', trigger: 'blur' }]"
                                        :name="['componentList', index, 'inputLimit']"
                                    >
                                        <a-input
                                            v-model:value="
                                                statisticsState.statisticsForm.componentList[index].inputLimit
                                            "
                                        />
                                    </a-form-item>
                                </div>
                            </div>
                            <a-divider
                                v-if="!index == statisticsState.statisticsForm.componentList.length - 1"
                                style="height: 1px; background-color: #3875ff; margin: 16px 0"
                            />
                        </div>
                    </div>
                </a-form>
            </a-modal>
            <!--新建信息统计-->
            <div class="tabs-content">
                <a-tabs v-model:activeKey="activeKey">
                    <a-tab-pane key="项目进度表" tab="项目进度表" />
                    <a-tab-pane key="整体进展" tab="整体进展" force-render />
                    <a-tab-pane key="分批进展" tab="分批进展" />
                    <a-tab-pane key="验证验收预测" tab="验证验收预测" />
                </a-tabs>
            </div>
            <template v-if="activeKey === '项目进度表'">
                <div class="top-search">
                    <a-form>
                        <a-row :gutter="24">
                            <a-col :span="6">
                                <a-form-item label="区域" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                    <a-select
                                        allow-clear
                                        show-search
                                        mode="multiple"
                                        v-model:value="state.filter.areaName"
                                        :options="state.areaNameList"
                                        placeholder="请选择"
                                        :field-names="{ label: 'label', value: 'value' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :max-tag-count="2"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="6">
                                <a-form-item label="项目总监" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                    <a-select
                                        allow-clear
                                        show-search
                                        mode="multiple"
                                        v-model:value="state.filter.projectDirector"
                                        :options="state.projectDirectorList"
                                        placeholder="请选择"
                                        :field-names="{ label: 'label', value: 'value' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :max-tag-count="2"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="6">
                                <a-form-item label="批次" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                    <a-select
                                        allow-clear
                                        show-search
                                        v-model:value="state.filter.batch"
                                        :options="state.batchList"
                                        placeholder="请选择"
                                        :field-names="{ label: 'name', value: 'name' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="6">
                                <a-form-item label="里程碑阶段" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }">
                                    <a-select
                                        allow-clear
                                        mode="multiple"
                                        :max-tag-count="2"
                                        v-model:value="state.filter.milepostName"
                                        :options="state.milepostList"
                                        :field-names="{ label: 'stageName', value: 'stageName' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.stageName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        placeholder="请选择"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24">
                            <a-col :span="6">
                                <a-form-item label="项目状态" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                    <a-select
                                        allow-clear
                                        placeholder="请选择"
                                        mode="multiple"
                                        v-model:value="state.filter.projectStatusList"
                                        :field-names="{ label: 'itemName', value: 'itemName' }"
                                        :options="state.statusList"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="6">
                                <a-form-item label="风险等级" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                    <a-select
                                        allow-clear
                                        placeholder="请选择"
                                        :options="state.fxdjList"
                                        :field-names="{ label: 'itemName', value: 'itemName' }"
                                        v-model:value="state.filter.riskLevel"
                                        mode="multiple"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="6">
                                <a-form-item label="预计结束" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                    <a-range-picker
                                        style="width: 100%"
                                        v-model:value="state.filter.expectEndTime"
                                        valueFormat="YYYY-MM-DD"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="6" v-if="toggle">
                                <a-form-item label="水泥专家" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }">
                                    <a-select
                                        allow-clear
                                        show-search
                                        mode="multiple"
                                        v-model:value="state.filter.businessExpert"
                                        :options="state.allUser"
                                        placeholder="请选择"
                                        :field-names="{ label: 'name', value: 'name' }"
                                        :filterOption="
                                            (input, option) => {
                                                return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                            }
                                        "
                                        :max-tag-count="2"
                                        :getPopupContainer="getPopupContainer"
                                    />
                                </a-form-item>
                            </a-col>
                            <a-col :span="6" style="display: flex; justify-content: end" v-if="!toggle">
                                <a-space :size="16">
                                    <div @click="toggleDiv" class="toggle-content">
                                        {{ toggle ? '收起' : '展开' }}<DoubleRightOutlined class="active-icon"
                                    /></div>
                                    <a-button type="primary" @click="resetData">重置</a-button>
                                </a-space>
                            </a-col>
                        </a-row>

                        <template v-if="toggle">
                            <a-row :gutter="24">
                                <a-col :span="6">
                                    <a-form-item label="项目经理" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                        <a-select
                                            allow-clear
                                            show-search
                                            mode="multiple"
                                            v-model:value="state.filter.pmName"
                                            :options="state.allUser"
                                            placeholder="请选择"
                                            :field-names="{ label: 'name', value: 'name' }"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                            :max-tag-count="2"
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6">
                                    <a-form-item label="客成经理" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                        <a-select
                                            allow-clear
                                            show-search
                                            mode="multiple"
                                            v-model:value="state.filter.preSaleManager"
                                            :options="state.allUser"
                                            placeholder="请选择"
                                            :field-names="{ label: 'name', value: 'name' }"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                            :max-tag-count="1"
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6">
                                    <a-form-item label="PMO" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                        <a-select
                                            allow-clear
                                            show-search
                                            mode="multiple"
                                            v-model:value="state.filter.pmo"
                                            :options="state.allUser"
                                            placeholder="请选择"
                                            :field-names="{ label: 'name', value: 'name' }"
                                            :filterOption="
                                                (input, option) => {
                                                    return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                }
                                            "
                                            :max-tag-count="1"
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6">
                                    <a-form-item label="转售后" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }">
                                        <a-select
                                            :options="[
                                                {
                                                    label: '全部',
                                                    value: '全部'
                                                },
                                                {
                                                    label: '是',
                                                    value: '是'
                                                },
                                                {
                                                    label: '否',
                                                    value: '否'
                                                }
                                            ]"
                                            v-model:value="state.filter.afterSalesStatus"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6">
                                    <a-form-item label="阶段" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                        <a-select
                                            allow-clear
                                            :max-tag-count="2"
                                            v-model:value="state.filter.milepostExpectEndTimeSearch.milepostName"
                                            :options="state.milepostList"
                                            :field-names="{ label: 'stageName', value: 'stageName' }"
                                            :filterOption="
                                                (input, option) => {
                                                    return (
                                                        option.stageName.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                                    )
                                                }
                                            "
                                            placeholder="请选择"
                                            :getPopupContainer="getPopupContainer"
                                        />
                                    </a-form-item>
                                </a-col>
                                <a-col :span="6">
                                    <a-form-item label="时间" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
                                        <a-range-picker
                                            style="width: 100%"
                                            v-model:value="state.filter.milepostExpectEndTimeSearch.expectEndTime"
                                            valueFormat="YYYY-MM-DD"
                                        />
                                    </a-form-item>
                                </a-col>

                                <a-col :span="12" style="display: flex; justify-content: end" v-if="toggle">
                                    <a-space :size="16">
                                        <div @click="toggleDiv" class="toggle-content"
                                            >{{ toggle ? '收起' : '展开'
                                            }}<DoubleRightOutlined class="active-icon-down"
                                        /></div>
                                        <a-button type="primary" @click="resetData" ghost>重置</a-button>
                                    </a-space>
                                </a-col>
                            </a-row>
                        </template>
                    </a-form>
                </div>
                <div class="body">
                    <div class="main">
                        <div class="table-tip">
                            <div class="left-top">
                                <div class="tip-title">项目进度列表</div>
                            </div>
                            <div class="right-top">
                                <div>表头含下划线的字段支持双击表格编辑详细内容</div>
                                <a-space :size="16">
                                    <a-button
                                        type="primary"
                                        v-permission="'3000001130_vid_47kf4mwgr0'"
                                        @click="exportExcel"
                                        :loading="exportLoading"
                                        >导出</a-button
                                    >
                                    <a-button type="primary" @click="getData">刷新</a-button>
                                    <!--                           <a-button type="primary" @click="handleJumpHy">会议纪要</a-button>-->
                                    <a-button
                                        type="primary"
                                        v-permission="'3000001130_vid_erot67zczj'"
                                        @click="showStatistics"
                                        >信息统计</a-button
                                    >
                                    <a-button
                                        @click="showSetting"
                                        v-permission="'3000001130_vid_s2ee8w2680'"
                                        type="primary"
                                        >显示设置</a-button
                                    >
                                </a-space>

                                <div class="icon-right">
                                    <div class="icon-right" @click="openFullscreen" v-if="!state.isFullScreen">
                                        <fullscreen-outlined class="toggle-icon" />全屏
                                    </div>
                                    <div class="icon-right" @click="closeFullscreen" v-else>
                                        <fullscreen-outlined class="toggle-icon" />退出全屏
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="top-classification">
                            <div class="total-num">
                                <div class="total-item">
                                    数据总数：
                                    <span class="nums-top" style="color: #3875ff">{{ state.num.total }}</span
                                    ><span style="color: #3875ff">个</span>
                                </div>
                            </div>
                            <div class="other-num">
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    运维： <span class="nums-top">{{ state.num.yw }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    验收完成阶段： <span class="nums-top">{{ state.num.yswc }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    验收阶段： <span class="nums-top">{{ state.num.ys }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    验证阶段： <span class="nums-top">{{ state.num.yz }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    正式运行阶段： <span class="nums-top">{{ state.num.zzyx }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    试运行阶段： <span class="nums-top">{{ state.num.sys }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    数据建模阶段： <span class="nums-top">{{ state.num.jm }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    <div class="border-item"></div>
                                    自学习数据确认： <span class="nums-top">{{ state.num.sjcjzl }}</span
                                    >个
                                </div>
                                <div class="classification-item">
                                    数据积累阶段： <span class="nums-top">{{ state.num.sjjl }}</span
                                    >个
                                </div>
                            </div>
                        </div>
                        <div class="kb-table-box">
                            <a-table
                                :key="tableKey"
                                :columns="filteredColumns"
                                :dataSource="state.dataSource"
                                :scroll="{ x: 'max-content', y: state.tableHeight }"
                                :pagination="false"
                                :loading="state.tableLoading"
                                bordered
                                @resizeColumn="handleResizeColumn"
                                :showSorterTooltip="false"
                                @change="handleTableChange"
                                ref="tableRef"
                                :rowClassName="() => 'custom-hover-row'"
                            >
                                <template #headerCell="{ column, title }">
                                    <template v-if="['进展', '问题&风险'].includes(title)">
                                        <div class="text-line-div">{{ title }}</div>
                                    </template>
                                    <template v-if="title === '项目状态'">
                                        <div class="text-line-div">
                                            {{ title }}
                                        </div>
                                    </template>
                                    <template v-if="title === '工厂名称'">
                                        <div class="text-line-div">
                                            {{ title }}
                                        </div>
                                    </template>
                                    <template v-if="column.dataIndex === 'riskLevel'">
                                        <span>
                                            {{ title }}
                                            <a-tooltip>
                                                <template #title>
                                                    <p class="risk-level-tool-tip">风险等级划分：</p>
                                                    <p class="risk-level-tool-tip">1、保底；</p>
                                                    <p class="risk-level-tool-tip">2、略有风险；</p>
                                                    <p class="risk-level-tool-tip">3、需要冲刺；</p>
                                                    <p class="risk-level-tool-tip">4、暂不强推</p>
                                                </template>
                                                <question-circle-outlined />
                                            </a-tooltip>
                                        </span>
                                    </template>
                                </template>

                                <template #bodyCell="{ record, text, column, index }">
                                    <template v-if="column.fieldType !== 'FILE' && column.fieldType">
                                        <div class="db-click" @dblclick="showEditStatistics(column, record, index)">{{
                                            text
                                        }}</div>
                                    </template>
                                    <template v-if="column.dataIndex === 'areaName'">
                                        {{ text }}
                                    </template>

                                    <template v-if="column.fieldType === 'FILE'">
                                        <div class="file-div" @dblclick="showEditStatistics(column, record, index)">
                                            <template v-if="text">
                                                <div v-for="(item, index) in JSON.parse(text)" :key="item.name">
                                                    <a-dropdown>
                                                        <a :title="item.name">{{ item.name }}</a>
                                                        <template #overlay>
                                                            <a-menu>
                                                                <a-menu-item>
                                                                    <a-button
                                                                        type="link"
                                                                        size="small"
                                                                        :disabled="!item.type.startsWith('image')"
                                                                        @click="viewImage(item.url)"
                                                                        >预览</a-button
                                                                    >
                                                                </a-menu-item>
                                                                <a-menu-item>
                                                                    <a-button
                                                                        type="link"
                                                                        size="small"
                                                                        @click="downLoadFile(item)"
                                                                        >下载</a-button
                                                                    >
                                                                </a-menu-item>
                                                            </a-menu>
                                                        </template>
                                                    </a-dropdown>
                                                </div>
                                            </template>
                                            <template v-else>
                                                <div class="file-div"></div>
                                            </template>
                                        </div>
                                    </template>

                                    <template v-if="['里程碑阶段'].includes(column.title)">
                                        <div class="db-click" @dblclick="changeData(record, index)">{{ text }}</div>
                                    </template>
                                    <template v-if="column.dataIndex === 'progress'">
                                        <div class="progress-click" @dblclick="changeData(record, index)">
                                            <a-tooltip
                                                :overlay-style="overStyle"
                                                v-if="record.progress"
                                                placement="right"
                                            >
                                                <template #title>
                                                    <template v-if="text">
                                                        <!--                                                            <div v-for="(item, index) in handlerGetSpace(text)">-->
                                                        <!--                                                                {{ item?.trim() }}-->
                                                        <!--                                                            </div>-->
                                                        <div style="white-space: pre-wrap; word-break: break-word">{{
                                                            text
                                                        }}</div>
                                                    </template> </template
                                                ><div class="omit-div">{{ text }} </div>
                                            </a-tooltip>
                                            <div class="plus-icon" @click="handleAddProgress(record)"
                                                ><PlusCircleOutlined
                                            /></div>
                                        </div>
                                    </template>
                                    <template v-if="column.dataIndex === 'question'">
                                        <div class="question-div" @dblclick="changeData(record, index)">
                                            <a-tooltip
                                                :overlay-style="overStyle"
                                                v-if="record.question"
                                                placement="right"
                                            >
                                                <template #title>
                                                    <!--                        {{ record.question }}【 {{ record.operator }}】【{{-->
                                                    <!--                          record.operateTime-->

                                                    <!--                        }}】-->
                                                    <template v-if="text">
                                                        <!--                                                            <div v-for="(item, index) in handlerGetSpace(text)">-->
                                                        <!--                                                                {{ item?.trim() }}-->
                                                        <!--                                                            </div>-->
                                                        <div style="white-space: pre-wrap; word-break: break-word">{{
                                                            text
                                                        }}</div>
                                                        <!--                                                        <div>【 {{ record.operator }}】</div>-->
                                                        <div>【{{ record.operateTime }}】</div>
                                                    </template> </template
                                                ><div class="omit-div-question"
                                                    ><span v-if="record.question"
                                                        >{{ text }}【 {{ record.operator }}】【{{
                                                            record.operateTime
                                                        }}】</span
                                                    ></div
                                                >
                                            </a-tooltip>
                                            <div class="plus-icon" @click="handleAddLhwt(record)"
                                                ><PlusCircleOutlined
                                            /></div>
                                        </div>
                                    </template>
                                    <template v-if="column.dataIndex === 'productionPlan'">
                                        <div class="productionPlan-div">
                                            <a-tooltip
                                                :overlay-style="overStyle"
                                                v-if="record.productionPlan"
                                                placement="right"
                                            >
                                                <template #title>{{ text }}</template
                                                ><div class="omit-div-productionPlan" v-if="text">{{ text }}</div>
                                            </a-tooltip>
                                        </div>
                                    </template>
                                    <template v-if="column.dataIndex === 'customerRelationship'">
                                        <div class="customerRelationship-div">
                                            <a-tooltip
                                                :overlay-style="overStyle"
                                                v-if="record.customerRelationship"
                                                placement="right"
                                            >
                                                <template #title>{{ text }}</template
                                                ><div class="omit-div-customerRelationship"
                                                    ><span v-if="text">{{ text }}</span></div
                                                >
                                            </a-tooltip>
                                        </div>
                                    </template>
                                    <template v-if="column.dataIndex === 'count'">
                                        {{ index + 1 }}
                                    </template>
                                    <template
                                        v-if="
                                            [
                                                'modelExpectStartTime',
                                                'modelExpectEndTime',
                                                'testRunExpectStartTime',
                                                'testRunExpectEndTime',
                                                'runExpectStartTime',
                                                'runExpectEndTime',
                                                'checkExpectStartTime',
                                                'checkExpectEndTime',
                                                'verifyExpectStartTime',
                                                'verifyExpectEndTime'
                                            ].includes(column.dataIndex)
                                        "
                                    >
                                        <div class="db-click" @dblclick="changeData(record, index)">{{ text }}</div>
                                    </template>
                                    <template v-if="column.dataIndex === 'supportors'">
                                        <div class="support-div" :title="text" @dblclick="changeData(record, index)">{{
                                            text
                                        }}</div>
                                    </template>
                                    <template v-if="column.dataIndex === 'projectStatus'">
                                        <div
                                            v-if="record.projectStatus === '进行中'"
                                            class="db-click status-div"
                                            @dblclick="changeData(record, index)"
                                            :style="{ backgroundColor: getTextColor(text) }"
                                            >{{ text }}</div
                                        >
                                        <div
                                            v-if="record.projectStatus === '准备'"
                                            class="db-click status-div"
                                            @dblclick="changeData(record, index)"
                                            :style="{ backgroundColor: getTextColor(text) }"
                                            >{{ text }}</div
                                        >
                                        <div
                                            v-if="record.projectStatus === '完成'"
                                            class="db-click status-div"
                                            @dblclick="changeData(record, index)"
                                            :style="{ backgroundColor: getTextColor(text) }"
                                            >{{ text }}</div
                                        >
                                        <div
                                            v-if="record.projectStatus === '售后'"
                                            class="db-click status-div"
                                            @dblclick="changeData(record, index)"
                                            :style="{ backgroundColor: getTextColor(text) }"
                                            >{{ text }}</div
                                        >
                                        <div
                                            v-if="!record.projectStatus"
                                            class="db-click"
                                            @dblclick="changeData(record, index)"
                                            >{{ text }}</div
                                        >
                                    </template>
                                    <template v-if="column.dataIndex === 'projectShortName'">
                                        <div class="db-click" @dblclick="changeData(record, index)">{{ text }}</div>
                                    </template>
                                    <template
                                        v-if="
                                            [
                                                'modelDevition',
                                                'testRunDevition',
                                                'runDevition',
                                                'verifyDevition',
                                                'checkDevition'
                                            ].includes(column.dataIndex)
                                        "
                                    >
                                        <div :style="getBgcColor(text)">{{ text }}</div>
                                    </template>
                                    <template v-if="column.dataIndex === 'operation'">
                                        <a-space :size="0">
                                            <a-button
                                                size="small"
                                                type="text"
                                                style="color: #3875ff"
                                                v-permission="'3000001130_vid_yh8k82d7nd'"
                                                :disabled="
                                                    !record.projectDirectorPermission &&
                                                    !record.pmPermission &&
                                                    !record.edit
                                                "
                                                @click="handleChangePlan(record, record.id, '计划调整', useTabName)"
                                                >变更</a-button
                                            >

                                            <a-button
                                                size="small"
                                                type="text"
                                                style="color: #3875ff"
                                                v-permission="'3000001130_vid_xgb4ftp6gq'"
                                                @click="handleShowChange(record, record.id, '查看计划', useTabName)"
                                                >变更记录</a-button
                                            >
                                            <a-button
                                                size="small"
                                                type="text"
                                                v-permission="'3000001130_vid_d53gpn96h1'"
                                                style="color: #3875ff"
                                                @click="jumpWorkOrder(record)"
                                                >工单</a-button
                                            >
                                            <a-button
                                                size="small"
                                                type="text"
                                                style="color: #3875ff"
                                                @click="jumpProject(record)"
                                                >项目</a-button
                                            >
                                        </a-space>
                                    </template>
                                </template>
                            </a-table>
                        </div>
                    </div>
                </div>
            </template>
            <template v-if="activeKey === '整体进展'">
                <OverallProgress />
            </template>
            <template v-if="activeKey === '分批进展'">
                <BatchesProgress />
            </template>
            <template v-if="activeKey === '验证验收预测'">
                <PredictionProgress />
            </template>
            <!-- end vid_01q526lihn 自定义模板_oo6ulgwhjy -->
        </a-spin>
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'

    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        },
        'tabName': {
            type: [String],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    const useTabName = ref('')
    import { watchEffect } from 'vue'
    const { tabName } = props
    watchEffect(() => {
        if (props.tabName) {
            useTabName.value = props.tabName
        }
    })
    let getPopupContainer
    onMounted(async () => {
        document.addEventListener('fullscreenchange', handleFullscreenChange, calcTableHeight)
        document.addEventListener('webkitfullscreenchange', handleFullscreenChange, calcTableHeight)
        document.addEventListener('mozfullscreenchange', handleFullscreenChange, calcTableHeight)
        document.addEventListener('MSFullscreenChange', handleFullscreenChange, calcTableHeight)
        getPopupContainer = () => document.body
        getMilePost()
        getStatus()
        getFxdj()
        getHyly()
        getFxLx()
        getZh()
        getExportPermission()
        getBatchList()
        getColumns()

        getAllUser()
        getAreaList()
        getBaseList()
        getColorConfig()
    })
    const height = window.innerHeight
    const headerOffset = ref(340)
    const topHeightNum = ref()
    const calcTableHeight = () => {
        // let topHeight = document.querySelector('.top-classification')
        // if (topHeight) {
        //     console.log(topHeight.offsetHeight)
        //     topHeightNum.value = topHeight.offsetHeight
        // }
        // let newNum = topHeightNum.value -50
        state.tableHeight = window.innerHeight - 180 - headerOffset.value
    }

    onMounted(() => {
        calcTableHeight()
        window.addEventListener('resize', calcTableHeight)
    })

    onBeforeUnmount(() => {
        window.removeEventListener('resize', calcTableHeight)
    })
    onUnmounted(() => {
        document.removeEventListener('fullscreenchange', handleFullscreenChange, calcTableHeight)
        document.removeEventListener('webkitfullscreenchange', handleFullscreenChange, calcTableHeight)
        document.removeEventListener('mozfullscreenchange', handleFullscreenChange, calcTableHeight)
        document.removeEventListener('MSFullscreenChange', handleFullscreenChange, calcTableHeight)
    })

    function closeFullscreen() {
        if (document.exitFullscreen) {
            document.exitFullscreen()
        } else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen() // 兼容 Firefox
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen() // 兼容 Chrome, Safari 和 Opera
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen() // 兼容 IE/Edge
        }

        // 恢复目标元素的样式
        const targetElement = document.querySelector('.page_root')
        if (targetElement) {
            targetElement.style.position = ''
            targetElement.style.top = ''
            targetElement.style.left = ''
            targetElement.style.width = ''
            targetElement.style.height = ''
            targetElement.style.zIndex = '' // 恢复 z-index
        }

        // state.isEditTable = true
        state.isFullScreen = false
        state.tableHeight = '400px'
        const text = document.querySelector('.text-lg')
        if (text) {
            text.style.display = '··'
        }
        headerOffset.value = 320
        calcTableHeight()
    }

    function openFullscreen() {
        // const elem = document.querySelector('.main') // 可以将元素设置为全屏
        const elem = document.body // 可以将元素设置为全屏
        if (elem.requestFullscreen) {
            elem.requestFullscreen()
        } else if (elem.mozRequestFullScreen) {
            elem.mozRequestFullScreen() // 兼容 Firefox
        } else if (elem.webkitRequestFullscreen) {
            elem.webkitRequestFullscreen() // 兼容 Chrome, Safari 和 Opera
        } else if (elem.msRequestFullscreen) {
            elem.msRequestFullscreen() // 兼容 IE/Edge
        }
        // state.isEditTable = false
        state.isFullScreen = true
        if (toggle.value) {
            state.tableHeight = '540px'
        } else {
            state.tableHeight = '620px'
        }

        // 模拟全屏：将目标元素调整为占满全屏的样式
        const targetElement = document.querySelector('.page_root') // 目标元素
        if (targetElement) {
            targetElement.style.position = 'fixed'
            targetElement.style.top = '0'
            targetElement.style.left = '0'
            targetElement.style.width = '100vw'
            targetElement.style.height = '100vh'
            targetElement.style.zIndex = '9999' // 设置一个高的 z-index，确保全屏内容在最上层
        }
        const text = document.querySelector('.text-lg')
        if (text) {
            text.style.display = 'none'
        }
        headerOffset.value = 230
        calcTableHeight()
    }
    function handleFullscreenChange() {
        // 检查整个文档是否处于全屏状态，并更新状态
        const isFullscreen =
            !!document.fullscreenElement ||
            !!document.mozFullScreenElement ||
            !!document.webkitFullscreenElement ||
            !!document.msFullscreenElement
        state.isFullScreen = isFullscreen
        const targetElement = document.querySelector('.page_root') // 目标元素
        const text = document.querySelector('.text-lg')
        if (targetElement) {
            if (!isFullscreen) {
                targetElement.style.position = ''
                targetElement.style.top = ''
                targetElement.style.left = ''
                targetElement.style.width = ''
                targetElement.style.height = ''
                targetElement.style.zIndex = '' // 恢复 z-index

                text.style.display = ''
                headerOffset.value = 320
                calcTableHeight()
            } else {
                targetElement.style.position = 'fixed'
                targetElement.style.top = '0'
                targetElement.style.left = '0'
                targetElement.style.width = '100vw'
                targetElement.style.height = '100vh'
                targetElement.style.zIndex = '9999' // 设置一个高的 z-index，确保全屏内容在最上层

                text.style.display = 'none'
                headerOffset.value = 230
                calcTableHeight()
            }
        }
    }

    const radioStyle = reactive({
        display: 'flex',
        height: '30px',
        lineHeight: '30px'
    })
    const state = reactive({
        tableHeight: '400px',
        isEditTable: true,
        dataSource: [],
        checkList: [],
        baseCheckList: [],
        milepostCheckList: [],
        baseAllCheck: false,
        allBaseOptions: [
            '批次',
            '项目总监',
            '水泥专家',
            '项目经理',
            '熟料算法',
            '水泥算法',
            '客成经理',
            '客户满意工程师',
            'PMO',
            '项目阶段',
            '项目状态',
            '转售后'
        ], // 所有选项
        allmileOptions: [], // 所有选项
        alltimeOptions: ['计划开始', '计划结束', '实际开始', '实际结束', '预计开始', '预计结束'], // 所有选项
        allotherOptions: [
            '进展',
            '问题风险',
            '风险等级',
            '项目支持',
            '正式运行持续天数',
            '综合样20次',
            '降本空间',
            '生产计划',
            '客情关系'
        ], // 所有选项
        timeAllCheck: false,
        mileAllCheck: false,
        otherAllCheck: true,
        otherCheckList: [],
        settingVisible: false,
        editStatusVisible: false,
        addJzVisible: false,
        editJzVisible: false,
        jzContent: undefined,
        editJzContent: undefined,
        tableLoading: false,
        permission: true,
        exportPermission: true,
        fold: true,
        isFullScreen: false,
        areaNameList: [],
        projectDirectorList: [],
        batchList: [],
        allUser: [],
        filter: {
            areaName: undefined,
            projectDirector: undefined,
            batch: undefined,
            milepostName: undefined,
            riskLevel: [],
            projectStatusList: [],
            expectEndTime: undefined,
            collectionMappingExpectEndTime: undefined,
            processingTableConfirmExpectEndTime: undefined,
            modelExpectEndTime: undefined,
            testRunExpectEndTime: undefined,
            runExpectEndTime: undefined,
            verifyExpectEndTime: undefined,
            checkExpectEndTime: undefined,
            maintenanceExpectEndTime: undefined,
            businessExpert: undefined,
            pmName: undefined,
            preSaleManager: undefined,

            milepostExpectEndTimeSearch: {
                milepostName: '',
                'expectEndTime': ['']
            },
            afterSalesStatus: ''
            // milepostOrder: false
        },
        milepostList: [],
        statusList: [],
        fxdjList: [],
        hylyList: [],
        fxlxList: [],
        customSort: {
            'sortDirection': 'ASC',
            'filed': 'AREA'
        },
        zhyList: [],
        changeForm: {
            milepostName: undefined,
            projectStatus: undefined,
            progress: undefined,
            projectProgressDetailList: [],
            projectProgressQuestionList: [],
            risk: undefined,
            modelExpectStartTime: undefined,
            modelExpectEndTime: undefined,
            modelStartTime: undefined,
            modelEndTime: undefined,
            modelActualStartTime: undefined,
            modelActualEndTime: undefined,
            testRunExpectStartTime: undefined,
            testRunExpectEndTime: undefined,
            testRunStartTime: undefined,
            testRunEndTime: undefined,
            testRunActualStartTime: undefined,
            testRunActualEndTime: undefined,
            runExpectStartTime: undefined,
            runExpectEndTime: undefined,
            runStartTime: undefined,
            runEndTime: undefined,
            runActualStartTime: undefined,
            runActualEndTime: undefined,
            checkExpectStartTime: undefined,
            checkExpectEndTime: undefined,
            checkStartTime: undefined,
            checkEndTime: undefined,
            checkActualStartTime: undefined,
            checkActualEndTime: undefined,
            verifyExpectStartTime: undefined,
            verifyExpectEndTime: undefined,
            verifyStartTime: undefined,
            verifyEndTime: undefined,
            verifyActualStartTime: undefined,
            verifyActualEndTime: undefined,
            collectionMappingPlanStartTime: undefined,
            collectionMappingPlanEndTime: undefined,
            collectionMappingActualStartTime: undefined,
            collectionMappingActualEndTime: undefined,
            collectionMappingExpectStartTime: undefined,
            collectionMappingExpectEndTime: undefined,
            processingTableConfirmPlanStartTime: undefined,
            processingTableConfirmPlanEndTime: undefined,
            processingTableConfirmActualStartTime: undefined,
            processingTableConfirmActualEndTime: undefined,
            processingTableConfirmExpectStartTime: undefined,
            processingTableConfirmExpectEndTime: undefined,
            maintenanceStartTime: undefined,
            maintenanceEndTime: undefined,
            maintenanceActualStartTime: undefined,
            maintenanceActualEndTime: undefined,
            maintenanceExpectStartTime: undefined,
            maintenanceExpectEndTime: undefined,
            supportors: undefined,
            riskLevel: undefined,
            runDays: undefined,
            comprehensiveSample: undefined,
            expectedCostReduction: undefined,
            productionPlan: undefined,
            customerRelationship: undefined
        },
        modalTitle: '',
        changeActivekey: '基本信息',
        changeIndex: undefined,
        changeLoading: false,
        changeIndexLoading: false,
        num: {
            total: undefined,
            ys: undefined,
            yswc: undefined,
            yw: undefined,
            yz: undefined,
            zzyx: undefined,
            sys: undefined,
            jm: undefined,
            sjjl: undefined,
            sjcjzl: undefined
        },
        activeKey: '基础信息'
    })

    const wtItem = {
        riskType: '',
        'question': '',
        'solution': '',
        'ownerList': [],
        'endTime': '',
        'status': '',
        'progressDescription': '',
        deleteFlag: true
    }
    function handleAddJz() {
        state.changeForm.projectProgressDetailList.unshift({
            progress: state.jzContent,
            modifyFlag: true,
            testTime: dayjs().format('YYYY-MM-DD')
        })
        cancelJz()
    }
    function cancelJz() {
        state.addJzVisible = false
        state.jzContent = undefined
    }
    function handleConfirmEditJz() {
        state.changeForm.projectProgressDetailList[0].progress = state.editJzContent
        state.changeForm.projectProgressDetailList[0].changeFlag = true
        cancelEditJz()
    }
    function handleDeleteJz(item, index) {
        state.changeForm.projectProgressDetailList.splice(index, 1)
    }
    function cancelEditJz() {
        state.editJzVisible = false
        state.editJzContent = undefined
    }
    function handleEditJz(item) {
        state.editJzContent = item.progress
        state.editJzVisible = true
    }
    function handleAddWt() {
        state.changeForm.projectProgressQuestionList.unshift({ ...wtItem })
    }
    function handlerDeleteWt(index) {
        state.changeForm.projectProgressQuestionList.splice(index, 1)
    }
    const customCellStyle = () => {
        return {
            style: {
                padding: '0 5px'
            }
        }
    }
    const customOkCellStyle = () => {
        return {
            style: {
                padding: '4px 16px'
            }
        }
    }
    const timesMap = [
        { label: '计划开始', field: 'planStartTime' },
        { label: '计划结束', field: 'planEndTime' },
        { label: '预计开始', field: 'expectStartTime' },
        { label: '预计结束', field: 'expectEndTime' },
        { label: '实际开始', field: 'actualStartTime' },
        { label: '实际结束', field: 'actualEndTime' }
    ]
    function generateStageColumns(stageList) {
        if (!stageList || stageList.length == 0) {
            return
        }
        return stageList.map((stage, index) => {
            return {
                title: stage.stageName,
                visible: computed(() => state.milepostCheckList.includes(stage.stageName)),
                align: 'center',
                children: timesMap.map(time => {
                    return {
                        title: time.label,
                        align: 'center',
                        key: `stage_${index}_${time.field}`,
                        dataIndex: ['projectProgressStageList', index, time.field],
                        width: 150,
                        visible: computed(() => state.checkList.includes(time.label)),
                        // customRender: ({ record }) => record.projectProgressStageList?.[index]?.[time.field] || '-',

                        customRender: ({ record }) => {
                            const stageData = record.projectProgressStageList?.[index]
                            const value = stageData?.[time.field]

                            return renderTimeCell(value, stageData, time.field)
                        },
                        sorter: (a, b) => {
                            const aVal = a.projectProgressStageList?.[index]?.[time.field]
                            const bVal = b.projectProgressStageList?.[index]?.[time.field]
                            if (!aVal && !bVal) return 0
                            if (!aVal) return -1
                            if (!bVal) return 1
                            // 假设是日期字符串，比较时间戳
                            return new Date(aVal).getTime() - new Date(bVal).getTime()
                        }
                    }
                })
            }
        })
    }
    function renderTimeCell(value, stageData, field) {
        if (field === 'expectEndTime') {
            const actualVal = stageData?.actualEndTime
            const isOverdue = value && !actualVal && new Date(value) < new Date()
            return h('span', { style: isOverdue ? 'color: red' : '' }, value || '-')
        }
        return value || '-'
    }

    // 获取数据
    let getSelectFlag = ref(false)
    function getData() {
        state.tableLoading = true
        post('/solution-ppm/api/v2/built-in-system-ppm/project_progress/search ', {
            ...state.filter,
            customSort: state.customSort,
            productLine: useTabName.value
        })
            .then(data => {
                if (data.code !== 200) {
                    state.dataSource = []
                    message.error(data.message)
                    return
                }

                state.dataSource = data.data.map(({ customDataMap, ...rest }) => ({
                    ...customDataMap, // 解构并展开 customDataMap 的内容
                    ...rest
                }))
                if (!getSelectFlag.value) {
                    state.projectDirectorList = [...new Set(data.data.map(item => item.projectDirector))].map(item => {
                        return {
                            label: item,
                            value: item
                        }
                    })
                    state.areaNameList = [...new Set(data.data.map(item => item.areaName))].map(item => {
                        return {
                            label: item,
                            value: item
                        }
                    })
                    getSelectFlag.value = true
                }
                const counts = {
                    ys: 0, // 验收阶段
                    yw: 0, // 运维阶段
                    yswc: 0, // 验收完成阶段
                    sjcjzl: 0, // 数据采集治理阶段
                    yz: 0, // 验证阶段
                    zzyx: 0, // 正式运行阶段
                    sys: 0, // 试运行阶段
                    jm: 0, // 建模阶段
                    sjjl: 0 // 数据积累阶段
                }
                data.data.forEach(item => {
                    switch (item.milepostName) {
                        case '验收':
                            if (item.projectStatus === '准备' || item.projectStatus === '进行中') {
                                counts.ys++
                            }
                            if (item.projectStatus === '完成') {
                                counts.yswc++ // 如果 projectStatus 为 完成，则验收完成数加 1
                            }
                            break
                        case '验证':
                            counts.yz++
                            break
                        case '正式运行':
                            counts.zzyx++
                            break
                        case '试运行':
                            counts.sys++
                            break
                        case '数据建模':
                            counts.jm++
                            break
                        case '数据积累':
                            counts.sjjl++
                            break
                        case '自学习数据确认':
                            counts.sjcjzl++
                            break
                        case '转售后':
                            counts.yw++
                            break
                        case '运维':
                            counts.yw++
                            counts.yswc++
                            break
                        default:
                            break
                    }
                })

                // 赋值到 state.num
                state.num.ys = counts.ys
                state.num.yswc = counts.yswc
                state.num.yz = counts.yz
                state.num.zzyx = counts.zzyx
                state.num.sys = counts.sys
                state.num.jm = counts.jm
                state.num.sjjl = counts.sjjl
                state.num.sjcjzl = counts.sjcjzl
                state.num.yw = counts.yw

                // 计算 total 总数
                state.num.total = data.data.length
                getPersonSetting()
                if (state.dataSource[0]) {
                    // 1. 生成动态阶段列

                    const stageColumns = generateStageColumns(state.dataSource[0]?.projectProgressStageList)
                    const hasInserted = columnState.columns.some(col =>
                        stageColumns.some(stageCol => stageCol.dataIndex === col.dataIndex)
                    )

                    if (!hasInserted) {
                        const milepostIndex = columnState.columns.findIndex(col => col.dataIndex === 'milepostName')
                        columnState.columns.splice(milepostIndex, 0, ...stageColumns)
                    }
                }
            })
            .finally(() => {
                state.tableLoading = false
            })
    }

    // 获取项目阶段
    function getMilePost() {
        post('/solution-ppm/api/v2/built-in-system-ppm/project_progress_stage_config/search', {
            'orderBy': 'id',
            'conditions': [
                {
                    'field': 'product_line',
                    'value': useTabName.value,
                    'operator': 'EQ',
                    'valueType': 'STRING'
                }
            ]
        }).then(data => {
            state.milepostList = data.data
            // state.milepostList = data.data
            state.allmileOptions = data.data.map(item => {
                return item.stageName
            })
        })
    }
    // 获取行项目状态
    function getStatus() {
        get(' /solution-ppm-basic-data/api/v1/dictionary/search/1001.XMZT').then(data => {
            state.statusList = data.data
        })
    }
    // 获取风险等级
    function getFxdj() {
        get(' /solution-ppm-basic-data/api/v1/dictionary/search/FXDJ').then(data => {
            state.fxdjList = data.data
        })
    }
    // 获取风险类型
    function getFxLx() {
        get(' /solution-ppm-basic-data/api/v1/dictionary/search/FXLX').then(data => {
            state.fxlxList = data.data
            lhwtState.fxlxList = data.data
        })
    }
    // 会议来源
    function getHyly() {
        get(' /solution-ppm-basic-data/api/v1/dictionary/search/LHWTKB.HYLY').then(data => {
            state.hylyList = data.data
        })
    }
    // 获取综合样20
    function getZh() {
        get(' /solution-ppm-basic-data/api/v1/dictionary/search/ZHY20').then(data => {
            state.zhyList = data.data
        })
    }
    const downloadExcel = (response, name) => {
        const blob = new Blob([response], {
            type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
        })
        const downloadElement = document.createElement('a')
        const href = window.URL.createObjectURL(blob) // 创建下载的链接
        downloadElement.href = href
        downloadElement.download = name // 下载后文件名
        document.body.appendChild(downloadElement)
        downloadElement.click() // 点击下载
        document.body.removeChild(downloadElement) // 下载完成移除元素
        window.URL.revokeObjectURL(href)
        return href
    }
    const exportLoading = ref(false)
    // 导出
    function exportExcel() {
        exportLoading.value = true
        post(
            '/solution-ppm/api/v2/built-in-system-ppm/project_progress/export',
            { ...state.filter, customSort: state.customSort, productLine: useTabName.value },
            {
                responseType: 'arraybuffer'
            }
        )
            .then(res => {
                downloadExcel(res, '里程碑进度表.xlsx')
            })
            .finally(() => {
                exportLoading.value = false
            })
    }
    function resetData() {
        state.customSort = {
            'sortDirection': 'ASC',
            'filed': 'AREA'
        }

        tableKey.value = Date.now() // 强制刷新 table，清除 sorter、filters
        state.filter.areaName =
            state.filter.milepostName =
            state.filter.batch =
            state.filter.projectDirector =
            state.filter.businessExpert =
            state.filter.pmName =
            state.filter.preSaleManager =
                undefined
        state.filter.afterSalesStatus = ''
        state.filter.milepostExpectEndTimeSearch.milepostName = undefined
        state.filter.milepostExpectEndTimeSearch.expectEndTime = []
        state.filter.expectEndTime = []
        state.filter.projectStatusList = []
        state.filter.riskLevel = []
        // state.filter.milepostOrder = false
        resetFilters()
        getData()
    }
    const tableKey = ref(Date.now())
    const overStyle = ref({
        maxWidth: '800px',
        fontSize: '16px'
    })
    const changeFormRef = ref(null)
    // 确定更改
    function confirmItemStatus() {
        changeFormRef.value
            .validate()
            .then(() => {
                state.changeLoading = true
                put('/solution-ppm/api/v2/built-in-system-ppm/project_progress/modify', state.changeForm)
                    .then(data => {
                        if (data.code !== 200) {
                            state.dataSource = []
                            message.error(data.message)
                            return
                        }
                        message.success(data.message)
                        state.editStatusVisible = false
                        getData()
                        getMilePost()
                    })
                    .finally(() => {
                        state.changeLoading = false
                    })
            })
            .catch(() => {
                //校验未通过执行这里
                const errorList = document.querySelectorAll('.ant3-form-item-has-error')
                errorList[0]?.scrollIntoView({
                    block: 'center',
                    behavior: 'smooth'
                })
            })
    }
    // 保存并打开下一个
    function confirmItemAndOpenNext() {
        changeFormRef.value.validate().then(() => {
            state.changeIndexLoading = true
            put('/solution-ppm/api/v2/built-in-system-ppm/project_progress/modify', state.changeForm)
                .then(data => {
                    if (data.code !== 200) {
                        state.dataSource = []
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    getData()
                    getMilePost()
                    state.changeActivekey = '基本信息'
                    const record = state.dataSource[state.changeIndex + 1]
                    currentData.value = record
                    Object.assign(state.changeForm, record)
                    state.modalTitle = `详情--${record.projectShortName}`
                    getTimeList(record).then(() => {
                        state.editStatusVisible = true
                        state.changeIndex++
                    })
                    planState.questionId = record.projectId
                    planState.projectId = record.projectId
                    planState.from = useTabName.value
                })
                .finally(() => {
                    state.changeIndexLoading = false
                })
        })
    }
    // 取消修改
    function cancelItem() {
        state.editStatusVisible = false
        state.changeForm = {
            milepostName: undefined,
            projectStatus: undefined,
            progress: undefined,
            projectProgressDetailList: [],
            projectProgressQuestionList: [],
            risk: undefined,
            modelExpectStartTime: undefined,
            modelExpectEndTime: undefined,
            modelStartTime: undefined,
            modelEndTime: undefined
        }
    }
    const currentData = ref({})
    function changeData(record, index) {
        if (!state.permission) {
            message.info('暂无权限')
            return
        }
        if (!state.isEditTable) {
            return
        }
        state.changeActivekey = '基本信息'
        currentData.value = record
        Object.assign(state.changeForm, record)
        state.modalTitle = `详情 --${record.projectShortName}`
        planState.questionId = record.projectId
        planState.projectId = record.projectId
        planState.from = useTabName.value
        getTimeList(record).then(() => {
            state.editStatusVisible = true
            state.changeIndex = index
        })
    }
    function getTimeList(record) {
        return get(
            `/solution-ppm/api/v2/built-in-system-ppm/project_progress/modify/expect/${useTabName.value}/${record.projectId}`
        ).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.changeForm.projectProgressStageList = data.data
        })
    }
    const OPERATION_COLUMN = {
        title: '操作',
        dataIndex: 'operation',
        resizable: true,
        fixed: 'right',
        align: 'center',
        ellipsis: true,
        width: 240,
        minWidth: 240,
        visible: true
    }
    const deviationColumns = [
        {
            title: '数据建模计划偏差',
            dataIndex: 'modelDevition',
            resizable: true,
            align: 'center',
            ellipsis: true,
            sorter: (a, b) => {
                const valA = Number(a.modelDevition)
                const valB = Number(b.modelDevition)
                return valA - valB // 升序排列；如果要降序可以写 valB - valA
            },
            // sortDirections: ['ascend', 'descend', 'ascend'], // 支持点击时正序、倒序、恢复
            width: 151,
            visible: true
        },
        {
            title: '试运行计划偏差',
            dataIndex: 'testRunDevition',
            resizable: true,
            align: 'center',
            ellipsis: true,
            sorter: (a, b) => {
                const valA = Number(a.testRunDevition)
                const valB = Number(b.testRunDevition)
                return valA - valB // 升序排列；如果要降序可以写 valB - valA
            },
            width: 151,
            visible: true
        },
        {
            title: '正式运行计划偏差',
            dataIndex: 'runDevition',
            resizable: true,
            align: 'center',
            sorter: (a, b) => {
                const valA = Number(a.runDevition)
                const valB = Number(b.runDevition)
                return valA - valB // 升序排列；如果要降序可以写 valB - valA
            },
            ellipsis: true,
            width: 151,
            visible: true
        },
        {
            title: '验证计划偏差',
            dataIndex: 'verifyDevition',
            resizable: true,
            align: 'center',
            sorter: (a, b) => {
                const valA = Number(a.verifyDevition)
                const valB = Number(b.verifyDevition)
                return valA - valB // 升序排列；如果要降序可以写 valB - valA
            },
            ellipsis: true,
            width: 151,
            visible: true
        },
        {
            title: '验收计划偏差',
            dataIndex: 'checkDevition',
            resizable: true,
            align: 'center',
            ellipsis: true,
            sorter: (a, b) => {
                const valA = Number(a.checkDevition)
                const valB = Number(b.checkDevition)
                return valA - valB // 升序排列；如果要降序可以写 valB - valA
            },
            width: 151,
            visible: true
        }
    ]
    const columnState = reactive({
        columns: [
            {
                title: '序号',
                dataIndex: 'count',
                align: 'center',
                width: 50,
                fixed: 'left',
                ellipsis: true
            },
            {
                'title': '区域',
                'dataIndex': 'areaName',
                ellipsis: true,
                fixed: 'left',
                align: 'center'
            },
            {
                title: '工厂名称',
                dataIndex: 'projectShortName',
                ellipsis: true,
                width: 120,
                fixed: 'left',
                align: 'center',
                customCell: customCellStyle
            },

            {
                title: '批次',
                dataIndex: 'batch',
                ellipsis: true,
                width: 80,
                align: 'center'
            },

            {
                title: '项目总监',
                dataIndex: 'projectDirector',
                ellipsis: true,
                align: 'center',
                width: 80,
                customCell: customCellStyle,
                visible: computed(() => state.baseCheckList.includes('项目总监'))
            },
            {
                title: '水泥专家',
                dataIndex: 'businessExpert',
                align: 'center',
                ellipsis: true,
                width: 80,
                visible: computed(() => state.baseCheckList.includes('水泥专家'))
            },
            {
                title: '项目经理',
                dataIndex: 'pmName',
                align: 'center',
                ellipsis: true,
                width: 80,
                customCell: customOkCellStyle,
                visible: computed(() => state.baseCheckList.includes('项目经理'))
            },
            {
                title: '熟料算法',
                dataIndex: 'clinkerAlgorithmExpert',
                align: 'center',
                ellipsis: true,
                width: 80,
                customCell: customOkCellStyle,
                visible: computed(() => state.baseCheckList.includes('熟料算法'))
            },
            {
                title: '水泥算法',
                dataIndex: 'cementAlgorithmExpert',
                align: 'center',
                ellipsis: true,
                width: 80,
                customCell: customOkCellStyle,
                visible: computed(() => state.baseCheckList.includes('水泥算法'))
            },
            {
                title: '客成经理',
                dataIndex: 'preSaleManager',
                align: 'center',
                ellipsis: true,
                width: 80,
                customCell: customOkCellStyle,
                visible: computed(() => state.baseCheckList.includes('客成经理'))
            },
            {
                title: '客户满意工程师',
                dataIndex: 'afterSalesEngineer',
                align: 'center',
                ellipsis: true,
                width: 120,
                customCell: customOkCellStyle,
                visible: computed(() => state.baseCheckList.includes('客户满意工程师'))
            },
            {
                title: 'PMO',
                dataIndex: 'pmo',
                align: 'center',
                ellipsis: true,
                width: 80,
                customCell: customOkCellStyle,
                visible: computed(() => state.baseCheckList.includes('PMO'))
            },
            {
                title: '里程碑阶段',
                dataIndex: 'milepostName',
                sorter: true,
                ellipsis: true,
                align: 'center',
                width: 150,
                visible: computed(() => state.baseCheckList.includes('项目阶段'))
            },
            {
                title: '项目状态',
                dataIndex: 'projectStatus',
                ellipsis: true,
                align: 'center',
                width: 80,
                visible: computed(() => state.baseCheckList.includes('项目状态'))
            },
            {
                title: '转售后',
                dataIndex: 'afterSalesStatus',
                ellipsis: true,
                align: 'center',
                width: 80,
                visible: computed(() => state.baseCheckList.includes('转售后'))
            },
            {
                title: '进展',
                dataIndex: 'progress',
                ellipsis: true,
                resizable: true,
                align: 'center',
                width: 350,
                minWidth: 350,
                visible: computed(() => state.otherCheckList.includes('进展'))
            },

            {
                title: '问题&风险',
                dataIndex: 'question',
                ellipsis: true,
                align: 'center',
                resizable: true,
                width: 350,
                minWidth: 350,
                visible: computed(() => state.otherCheckList.includes('问题风险'))
            },
            ...deviationColumns,
            {
                title: '风险等级',
                dataIndex: 'riskLevel',
                align: 'center',
                ellipsis: true,
                width: 120,
                visible: computed(() => state.otherCheckList.includes('风险等级'))
            },
            {
                title: '项目支持',
                dataIndex: 'supportors',
                align: 'center',
                ellipsis: true,
                width: 120,
                visible: computed(() => state.otherCheckList.includes('项目支持'))
            },
            {
                title: '正式运行持续天数',
                dataIndex: 'runDays',
                align: 'center',
                ellipsis: true,
                width: 120,
                visible: computed(() => state.otherCheckList.includes('正式运行持续天数'))
            },
            {
                title: '综合样20次',
                dataIndex: 'comprehensiveSample',
                align: 'center',
                ellipsis: true,
                width: 120,
                visible: computed(() => state.otherCheckList.includes('综合样20次'))
            },
            {
                title: '降本空间',
                dataIndex: 'expectedCostReduction',
                align: 'center',
                ellipsis: true,
                width: 120,
                visible: computed(() => state.otherCheckList.includes('降本空间'))
            },
            {
                title: '生产计划',
                dataIndex: 'productionPlan',
                resizable: true,
                align: 'center',
                ellipsis: true,
                width: 350,
                minWidth: 350,
                visible: computed(() => state.otherCheckList.includes('生产计划'))
            },
            {
                title: '客情关系',
                dataIndex: 'customerRelationship',
                resizable: true,
                align: 'center',
                ellipsis: true,
                width: 350,
                minWidth: 350,
                visible: computed(() => state.otherCheckList.includes('客情关系'))
            },

            OPERATION_COLUMN
            // 其他通用列
        ]
    })

    const tableRef = ref(null)
    function resetFilters() {
        tableRef.value?.clearFilters?.()
    }
    const filteredColumns = computed(() => {
        return columnState.columns
            .map(column => {
                const updatedColumn = {
                    ...column,
                    children:
                        column.children && Array.isArray(column.children)
                            ? column.children.filter(child => child.visible)
                            : []
                }

                if (updatedColumn.children.length === 0 && column.children?.length > 0) {
                    updatedColumn.visible = false
                }

                return updatedColumn.visible === false ? null : updatedColumn
            })
            .filter(Boolean)
    })
    const handleResizeColumn = (w, col) => {
        const width = w - 50 // 确保宽度被计算并且减去额外空间

        // 根据列标题来确定不同的 div
        let div = null
        if (col.title === '进展') {
            div = document.querySelectorAll('.omit-div')
        } else if (col.title.includes('问题&风险')) {
            div = document.querySelectorAll('.omit-div-question')
        } else if (col.title === '生产计划') {
            div = document.querySelectorAll('.omit-div-productionPlan')
        } else if (col.title === '客情关系') {
            div = document.querySelectorAll('.omit-div-customerRelationship')
        }

        // 如果找到了对应的 div，更新其宽度
        if (div.length > 0) {
            div.forEach(item => {
                item.style.width = `${width}px`
            })
            overStyle.value.maxWidth = `${width}px` // 更新 tooltip 最大宽度
        }

        // 更新 columnState 中的列宽
        columnState.columns = columnState.columns.map(item => {
            if (item.dataIndex === col.dataIndex) {
                return { ...item, width: w } // 更新该列的宽度
            }
            return item
        })

        // 如果列有子列，确保子列也能根据父列的宽度进行更新
        if (col.children) {
            col.children.forEach(child => {
                columnState.columns = columnState.columns.map(item => {
                    if (item.dataIndex === child.dataIndex) {
                        return { ...item, width: w } // 更新子列的宽度
                    }
                    return item
                })
            })
        }
    }

    watch(filteredColumns, newColumns => {})
    function getBatchList() {
        get(`/solution-ppm/api/v2/built-in-system-ppm/dashboard_config/batch_priority_time/里程碑进度表/批次`).then(
            data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                state.batchList = data.data
            }
        )
    }
    const handleTableChange = (pagination, filters, sorter) => {
        let currentSortDirection = 'ASC' // 默认排序方向为 ASC
        let currentField = 'AREA' // 默认字段为 AREA

        if (sorter.column && sorter.column.dataIndex === 'milepostName') {
            // 判断排序方向
            if (sorter.order === 'ascend') {
                currentSortDirection = 'ASC'
            } else if (sorter.order === 'descend') {
                currentSortDirection = 'DESC'
            }
            // 设置自定义排序
            state.customSort = {
                sortDirection: currentSortDirection,
                filed: 'MILEPOST' // 根据需要修改字段名
            }
        } else {
            // 如果没有对 'milepostName' 进行排序，使用默认排序
            state.customSort = {
                sortDirection: currentSortDirection,
                filed: currentField
            }
        }
        getData()
    }
    function getPermission() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project_progress/permission').then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.permission = data.data
        })
    }
    function getExportPermission() {
        get('/solution-ppm/api/v2/built-in-system-ppm/project_progress/download_permission').then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.exportPermission = data.data
        })
    }
    function getAllUser() {
        get('/solution-ppm/api/v2/built-in-system-ppm/pmgf/get/allUser').then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.allUser = data.data.userDtoList
        })
    }
    function showSetting() {
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/data_collect/display_metadata?productLine=${useTabName.value}`
        ).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            statisticsState.mockData = data.data
            state.settingVisible = true
        })
    }
    function confirmSetting() {
        statisticsState.settingLoading = true
        post('/solution-ppm/api/v2/built-in-system-ppm/project_progress/person_config/create', {
            baseCheckList: state.baseCheckList,
            milepostCheckList: state.milepostCheckList,
            checkList: state.checkList,
            otherCheckList: state.otherCheckList,
            dataCollectorList: statisticsState.targetKeys,
            productLine: useTabName.value
        })
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success('保存成功')
                state.settingVisible = false
                getColumns()
            })
            .finally(() => {
                statisticsState.settingLoading = false
            })
    }
    function getColumns() {
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/data_collect/display_metadata?productLine=${useTabName.value}`
        ).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }

            // 1. 获取所有可能的动态列元数据
            const allDynamicColumnsMetadata = data.data

            // 2. 过滤出当前应该显示的目标列
            const dynamicColumnsToShow = allDynamicColumnsMetadata
                .filter(item => statisticsState.targetKeys.includes(item.id))
                .map(item => ({
                    ...item,
                    dataIndex: item.englishName,
                    title: item.chinessName,
                    width: 300,
                    visible: true,
                    align: 'center'
                }))

            // 3. 分离出固定列（不包括操作列和动态列）
            const fixedColumns = columnState.columns.filter(
                col =>
                    col.fixed !== 'right' && // 排除操作列
                    !allDynamicColumnsMetadata.some(dynCol => dynCol.englishName === col.dataIndex) // 排除所有动态列
            )

            // 4. 分离出操作列
            const operationColumn = columnState.columns.find(col => col.fixed === 'right') || OPERATION_COLUMN

            // 5. 重新组合列：固定列 + 当前应显示动态列 + 操作列
            columnState.columns = [...fixedColumns, ...dynamicColumnsToShow, operationColumn]
        })
    }

    //     信息统计
    const statisticsState = reactive({
        targetKeys: [],
        selectedKeys: [],
        mockData: [],
        statisticsVisible: false,
        editStatisticsVisible: false,
        statisticsForm: {
            projectIdList: undefined,
            planEndTime: undefined,
            role: undefined,
            componentList: [
                {
                    zdmc: undefined,
                    componentType: undefined, //组件类型
                    selectType: undefined, //选择框类型
                    inputLimit: undefined, //input框数据
                    dateValue: [], //时间框数据
                    fileValue: undefined, //时间框数据
                    selectList: [{}], //选项列表
                    lableName: undefined //字段名称
                }
            ]
        },
        editForm: {
            projectIdList: undefined,
            planEndTime: undefined,
            value: undefined
        },
        treeData: [],
        addLoading: false,
        editLoading: false,
        settingLoading: false
    })
    // 组件类型改变
    function changeComponentType(index) {
        if (statisticsState.statisticsForm.componentList[index].componentType === 'SELECT') {
            statisticsState.statisticsForm.componentList[index].selectList = [{}]
            statisticsState.statisticsForm.componentList[index].inputLimit = undefined
            ;(statisticsState.statisticsForm.componentList[index].dateValue = []),
                (statisticsState.statisticsForm.componentList[index].fileValue = undefined)
        } else if (statisticsState.statisticsForm.componentList[index].componentType === '输入') {
            statisticsState.statisticsForm.componentList[index].selectType = undefined
            ;(statisticsState.statisticsForm.componentList[index].dateValue = []),
                (statisticsState.statisticsForm.componentList[index].selectList = []),
                (statisticsState.statisticsForm.componentList[index].fileValue = undefined)
        } else if (statisticsState.statisticsForm.componentList[index].componentType === 'DATE') {
            statisticsState.statisticsForm.componentList[index].selectType = undefined
            ;(statisticsState.statisticsForm.componentList[index].inputLimit = undefined),
                (statisticsState.statisticsForm.componentList[index].selectList = []),
                (statisticsState.statisticsForm.componentList[index].fileValue = undefined)
        } else if (statisticsState.statisticsForm.componentList[index].componentType === 'FILE') {
            statisticsState.statisticsForm.componentList[index].selectType = undefined
            ;(statisticsState.statisticsForm.componentList[index].inputLimit = undefined),
                (statisticsState.statisticsForm.componentList[index].selectList = []),
                (statisticsState.statisticsForm.componentList[index].dateValue = [])
        }
    }
    function getTreeData() {
        get(`/solution-ppm/api/v2/built-in-system-ppm/data_collect/tree?productLine=${useTabName.value}`).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            statisticsState.treeData = data.data
        })
    }
    const statisticsRef = ref(null)
    function showStatistics() {
        statisticsState.statisticsVisible = true
    }
    function cancelStatistics() {
        statisticsState.statisticsVisible = false
        statisticsState.statisticsForm = {
            projectIdList: undefined,
            planEndTime: undefined,
            role: undefined,
            componentList: [
                {
                    zdmc: undefined,
                    componentType: undefined,
                    selectType: undefined,

                    selectList: [{}],
                    lableName: undefined
                }
            ]
        }
    }
    // 新增字段
    function handleAddField() {
        if (statisticsState.statisticsForm.componentList.length == 5) {
            message.info('一次最多添加5个字段')
            return
        }
        statisticsState.statisticsForm.componentList.push({
            zdmc: undefined,
            componentType: undefined,
            selectType: undefined,
            inputLimit: undefined,
            dateValue: [],
            fileValue: undefined,
            selectList: [
                {
                    value: ''
                }
            ],
            lableName: undefined
        })
    }
    // 删除字段
    function handleDeleteField(index) {
        if (statisticsState.statisticsForm.componentList.length == 1) return
        statisticsState.statisticsForm.componentList.splice(index, 1)
    }
    // 新增选项
    function handleAddSelect(index, selectIndex) {
        statisticsState.statisticsForm.componentList[index].selectList.splice(selectIndex + 1, 0, {
            value: ''
        })
    }
    // 删除选项
    function handleDeleteSelect(index, selectIndex) {
        if (statisticsState.statisticsForm.componentList[index].selectList.length == 1) return
        statisticsState.statisticsForm.componentList[index].selectList.splice(selectIndex, 1)
    }
    function confirmStatistics() {
        statisticsRef.value
            .validate()
            .then(() => {
                statisticsState.addLoading = true
                const formattedData = {
                    ...statisticsState.statisticsForm, // 保留原数据
                    componentList: statisticsState.statisticsForm.componentList.map(item => ({
                        ...item, // 保留原有字段
                        selectList: item.selectList ? item.selectList.map(option => option.value) : [] // 格式化 selectList
                    })),
                    productLine: useTabName.value
                }
                post('/solution-ppm/api/v2/built-in-system-ppm/data_collect/fill_form/generate', formattedData)
                    .then(data => {
                        if (data.code !== 200) {
                            message.error(data.message)
                            return
                        }
                        message.success(data.message)
                        cancelStatistics()
                        getColumns()
                        getData()
                    })
                    .finally(() => {
                        statisticsState.addLoading = false
                    })
            })
            .catch(() => {
                //校验未通过执行这里
                const errorList = document.querySelectorAll('.ant3-form-item-has-error')
                errorList[0]?.scrollIntoView({
                    block: 'center',
                    behavior: 'smooth'
                })
            })
    }
    const currentNewField = ref({})
    function showEditStatistics(column, record, index) {
        post('/solution-ppm/api/v2/built-in-system-ppm/data_collect/meta_data/value/search', {
            'projectId': record.projectId,
            'column': column.dataIndex
        }).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            if (!data.data) {
                message.info('不在统计范围内！')
                return
            }
            currentNewField.value = data.data
            currentNewField.value.projectId = record.projectId
            currentNewField.value.column = column.dataIndex
            currentNewField.value.value = undefined
            currentNewField.value.fieldType = column.fieldType
            currentNewField.value.selectType = column.selectType
            currentNewField.value.inputLimit = column.inputLimit
            if (column.fieldType === 'SELECT' && (column.selectType === 'CHECK' || column.selectType === 'RADIO')) {
                currentNewField.value.selectList =
                    JSON.parse(column.selectList).map(item => {
                        return {
                            label: item,
                            value: item
                        }
                    }) || []
            } else if (column.fieldType === 'FILE') {
                currentNewField.value.selectList = JSON.parse(data.data[column.dataIndex])
            } else {
                currentNewField.value.selectList = []
            }
            currentNewField.value.label = column.title
            statisticsState.editForm.projectIdList = `${record.areaName}-${record.projectShortName}`
            statisticsState.editForm.planEndTime = column.planEndTime
            if (column.fieldType === 'SELECT' && column.selectType === 'CHECK') {
                statisticsState.editForm.value = data.data[column.dataIndex].split(',')
            } else if (column.fieldType === 'FILE') {
                statisticsState.editForm.value = JSON.parse(data.data[column.dataIndex])
            } else {
                statisticsState.editForm.value = data.data[column.dataIndex]
            }

            statisticsState.editStatisticsVisible = true
        })
    }
    const editStatisticsRef = ref(null)
    function handleValue(value) {
        if (Array.isArray(value)) {
            // 判断数组第一个元素是否为对象
            if (typeof value[0] === 'object') {
                // 如果数组中的元素是对象，则转为 JSON 字符串
                return JSON.stringify(value)
            } else {
                // 如果是普通数组（如['1', '2', '3']），转为逗号分隔的字符串
                return value.join(',')
            }
        }
        // 如果不是数组，直接返回原值
        return value
    }
    function confirmEditStatistics() {
        editStatisticsRef.value.validate().then(() => {
            statisticsState.editLoading = true
            const params = {
                'projectId': currentNewField.value.projectId,
                'column': currentNewField.value.column,
                'value': handleValue(statisticsState.editForm.value)
            }

            put('/solution-ppm/api/v2/built-in-system-ppm/data_collect/meta_data/value', params)
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    cancelEditStatistics()
                    getData()
                })
                .finally(() => {
                    statisticsState.editLoading = false
                })
        })
    }
    function cancelEditStatistics() {
        currentNewField.value = {}
        statisticsState.editStatisticsVisible = false
    }
    // 上传文件
    function handlerResolvedUpload(file) {
        const data = new FormData()
        data.append('file', file)

        post('/file-storage/api/v1/file/upload', data)
            .then(({ data: { fullUrl } }) => {
                if (data) {
                    // 新文件对象
                    const newFile = {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }

                    // 去重，保留一个副本
                    statisticsState.editForm.value = [
                        // 保留已存在文件（去除重复）
                        ...statisticsState.editForm.value.filter(
                            item => item.uid !== file.uid && item.name !== file.name
                        ),
                        // 添加新的文件
                        newFile
                    ]
                }
            })
            .catch(e => {
                message.error('上传失败' + e)
            })

        return false
    }
    // 移除文件
    function handlerResolvedRemove(file) {
        statisticsState.editForm.value = statisticsState.editForm.value.filter(item => item.uid !== file.uid)
    }
    // 打开图片的函数
    function viewImage(url) {
        window.open(url, '_blank') // 在新窗口打开图片
    }
    // 下载文件的函数
    function downLoadFile(item) {
        fetch(item.url)
            .then(response => response.blob())
            .then(blob => {
                const downloadLink = document.createElement('a')
                const url = URL.createObjectURL(blob)
                downloadLink.href = url
                downloadLink.setAttribute('download', item.name)
                downloadLink.style.display = 'none'
                document.body.appendChild(downloadLink)
                downloadLink.click()
                document.body.removeChild(downloadLink)

                // Release the object URL after the download
                URL.revokeObjectURL(url)
                pageLoading.loading = false
            })
            .catch(err => {
                console.error('Download failed', err)
            })
    }
    const isExpanded = ref(false) // 控制展开/折叠的状态

    // 展开111/折叠按钮切换
    const toggleExpand = () => {
        isExpanded.value = !isExpanded.value
    }

    //     信息统计
    async function getBaseList() {
        // 定义请求接口的 URL 或方法
        const requests = [
            get(' /solution-ppm-basic-data/api/v1/dictionary/search_tree/LHWTKB.WTLX'), // 问题类型
            get(' /solution-ppm-basic-data/api/v1/dictionary/search/LHWTKB.JJFA'), // 解决方案
            get(' /solution-ppm-basic-data/api/v1/dictionary/search/LHWTKB.FAQ'), // faq
            get(' /solution-ppm-basic-data/api/v1/dictionary/search/LHWTKB.TXBH') // 体系闭环
        ]

        try {
            // 使用 Promise.allSettled 确保所有请求都会执行
            const results = await Promise.allSettled(requests)

            // 处理每个请求的结果
            results.forEach((result, index) => {
                if (result.status === 'fulfilled') {
                    if (index === 0) {
                        lhwtState.wtlxList = result.value.data
                    } else if (index === 1) {
                        lhwtState.jjfaList = result.value.data.map(item => {
                            return {
                                label: item.itemName,
                                value: item.itemName
                            }
                        })
                    } else if (index === 2) {
                        lhwtState.faqList = result.value.data.map(item => {
                            return {
                                label: item.itemName,
                                value: item.itemName
                            }
                        })
                    } else if (index === 3) {
                        lhwtState.txbhList = result.value.data.map(item => {
                            return {
                                label: item.itemName,
                                value: item.itemName
                            }
                        })
                    }
                } else {
                    // 请求失败，打印错误
                    console.error(`接口 ${index + 1} 请求失败:`, result.reason)
                }
            })
        } catch (error) {
            // 捕获任何其他的错误（比如请求数组外的错误）
            console.error('请求出现意外错误:', error)
        }
    }
    // 问题新建
    const lhwtState = reactive({
        changeForm: {
            meetingDate: undefined,
            areaCode: undefined,
            solution: undefined,
            projectId: undefined,
            projectDirector: [],
            pmName: [],
            questionDescription: undefined,
            responsiblePersonList: undefined,
            endTime: undefined,
            riskType: undefined,
            meetingSourceList: [],
            completionStatusFeedback: undefined,
            questionTypeFirst: undefined,
            questionTypeSecond: undefined,
            faq: undefined,
            finishStatus: undefined,
            projectType: '交付项目',
            commonProblems: undefined,
            systemClosedLoop: undefined,
            solutionOrAction: undefined
        },
        addOrEditVisible: false,
        okLoading: false,
        modalTitle: '新建问题',
        filter: {
            areaCode: undefined,
            projectDirector: undefined,
            pmName: undefined,
            questionTypeSecond: undefined,
            solution: undefined,
            faq: undefined,
            systemClosedLoop: undefined
        },
        wtlxList: [],
        jjfaList: [],
        faqList: [],
        fxlxList: [],
        txbhList: [],
        areaNameList: [],
        projectList: [],
        projectDirectorList: [],
        pmNameList: [],
        allUser: [],
        dataSource: [],
        tableLoading: false
    })
    const lhwtRef = ref(null)
    function confirmLhwt() {
        lhwtRef.value.validate().then(() => {
            lhwtState.okLoading = true
            const api = currentLhwtData.value.id ? put : post
            api('/solution-ppm/api/v2/built-in-system-ppm/meeting_question', lhwtState.changeForm)
                .then(data => {
                    if (data.code !== 200) {
                        message.error(data.message)
                        return
                    }
                    message.success(data.message)
                    cancelLhwt()
                    getData()
                })
                .finally(() => {
                    lhwtState.okLoading = false
                })
        })
    }

    function handleAddLhwt(record) {
        planState.questionTitle = `问题&风险 -${record.projectShortName}`
        planState.questionId = record.projectId
        planState.projectId = record.projectId
        planState.from = useTabName.value
        planState.questionVisible = true
    }
    function cancelLhwt() {
        lhwtState.changeForm = {
            meetingDate: undefined,
            areaCode: undefined,
            solution: undefined,
            projectId: undefined,
            projectDirector: [],
            pmName: [],
            questionDescription: undefined,
            responsiblePersonList: undefined,
            endTime: undefined,
            completionStatusFeedback: undefined,
            questionTypeFirst: undefined,
            questionTypeSecond: undefined,
            faq: undefined,
            commonProblems: undefined,
            systemClosedLoop: undefined,
            solutionOrAction: undefined
        }
        currentLhwtData.value = {}
        lhwtState.addOrEditVisible = false
    }
    function changeLhwt(record) {
        currentLhwtData.value = record
        lhwtState.modalTitle = '编辑问题'
        let data = cloneDeep(record)
        Object.assign(lhwtState.changeForm, data)
        lhwtState.addOrEditVisible = true
    }
    // 区域
    function getAreaList() {
        get('/solution-ppm-work-order/api/v1/work_order/area_info').then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            lhwtState.areaNameList = data.data.map(item => {
                return {
                    label: item.areaName,
                    value: item.areaCode
                }
            })
        })
    }
    function getFactory() {
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/meeting_question/get_project_by_area_code/${lhwtState.changeForm.areaCode}`
        ).then(data => {
            lhwtState.projectList = data.data.map(item => {
                return {
                    label: item.projectShortName,
                    value: item.projectId,
                    pmName: item.pmName,
                    projectDirector: item.projectDirector
                }
            })
        })
    }
    function factoryChange() {
        let chooseData = lhwtState.projectList.find(item => item.value === lhwtState.changeForm.projectId)
        if (chooseData) {
            lhwtState.changeForm.projectDirector = chooseData.projectDirector?.split(',')[0]
            lhwtState.changeForm.pmName = chooseData.pmName
        }
    }
    function areaChange() {
        lhwtState.changeForm.pmName = lhwtState.changeForm.projectDirector = lhwtState.changeForm.projectId = undefined
    }
    const currentLhwtData = ref({})
    //     问题
    // 新-模板项目审核标准格式
    function handlerGetSpace(data) {
        return data?.split(/[;；]/)
    }
    const toggle = ref(false)
    function toggleDiv() {
        toggle.value = !toggle.value
    }
    watch(
        () => toggle.value,
        () => {
            // 新建项目阶段按钮
            if (toggle.value) {
                headerOffset.value += 80
            } else {
                // 折叠
                headerOffset.value -= 80
            }
            calcTableHeight()
        },
        {
            deep: true
        }
    )
    function handleJumpHy() {
        router.push(`${import.meta.env.VITE_PUBLIC_PATH}/page/3000000996`)
        // const url = `${import.meta.env.VITE_PUBLIC_PATH.replace(/\/$/, '')}/page/3000000988`
        // window.open(url, '_blank') // 在新标签页打开
    }
    // 新需求
    // 基础信息全选
    function baseAllChange() {
        state.baseCheckList = state.baseAllCheck ? [...state.allBaseOptions] : []
    }

    // 项目阶段全选
    function mileAllChange() {
        state.milepostCheckList = state.mileAllCheck ? [...state.allmileOptions] : []
    }

    // 时间全选
    function timeAllChange() {
        state.checkList = state.timeAllCheck ? [...state.alltimeOptions] : []
    }

    // 其他全选
    function otherAllChange() {
        state.otherCheckList = state.otherAllCheck ? [...state.allotherOptions] : []
    }
    // 监听单个选项的变化
    const handleBaseCheckChange = () => {
        state.baseAllCheck = state.baseCheckList.length === state.allBaseOptions.length
    }

    const handleMileCheckChange = () => {
        state.mileAllCheck = state.milepostCheckList.length === state.allmileOptions.length
    }

    const handleTimeCheckChange = () => {
        state.timeAllCheck = state.checkList.length === state.alltimeOptions.length
    }

    const handleOtherCheckChange = () => {
        state.otherAllCheck = state.otherCheckList.length === state.allotherOptions.length
    }
    watch(
        state.filter,
        newVal => {
            getData()
        },
        { immediate: true } // 立即执行一次
    )

    const activeKey = ref('项目进度表')
    import OverallProgress from './Page3000000998.vue'
    import BatchesProgress from './Page3000000997.vue'
    import PredictionProgress from './Page3000000999.vue'
    import FactoryMsg from './Page3000001001.vue'
    import { nextTick } from 'vue'
    function getPersonSetting() {
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/project_progress/person_config/search?productLine=${useTabName.value}`
        ).then(data => {
            state.baseCheckList = data.data.baseCheckList || []
            state.milepostCheckList = data.data.milepostCheckList || []
            state.checkList = data.data.checkList || []
            state.otherCheckList = data.data.otherCheckList || []
            statisticsState.targetKeys = data.data.dataCollectorList || []

            // 更新全选状态
            updateAllCheckStates()
        })
    }
    // 更新所有全选状态
    function updateAllCheckStates() {
        state.baseAllCheck = state.baseCheckList.length === state.allBaseOptions.length
        state.mileAllCheck = state.milepostCheckList.length === state.allmileOptions.length
        state.timeAllCheck = state.checkList.length === state.alltimeOptions.length
        state.otherAllCheck = state.otherCheckList.length === state.allotherOptions.length
    }
    const colorMap = {
        '进行中': '#3875FF',
        '准备': '#ffa940',
        '完成': 'green',
        '售后': '#ffa940'
    }
    function getTextColor(text) {
        return colorMap[text] || '#262626'
    }
    const endToEndRef = ref(null)
    const edgeSideRef = ref(null)

    // 新需求
    // 端到端

    import EndToEnd from './Page3000001076.vue'
    import EdgeSide from './Page3000001124.vue'
    // 端到端
    // 新需求
    // 端到端
    const planState = reactive({
        planChangeVisible: false,
        planChangeId: undefined,
        from: undefined,
        type: undefined,
        projectId: undefined,
        planChangeTitle: '',
        showChangeVisible: false,
        showChangeId: undefined,
        showChangeTitle: '',
        questionVisible: false,
        questionTitle: '',
        questionId: undefined
    })
    import PlanChange from './Page3000001077.vue'
    import Question from './Page3000001079.vue'
    const questionRef = ref(null)
    function handleAddQuestion() {
        // 通过 ref 调用子组件的新增方法
        questionRef.value?.handleAddTable()
    }
    function handleChangePlan(record, id, type, from) {
        planState.type = type
        planState.from = from
        planState.projectId = record.projectId
        planState.planChangeTitle = `预计变更 -${record.projectShortName}`
        planState.planChangeId = id
        planState.planChangeVisible = true
    }
    function handleShowChange(record, id, type, from) {
        planState.type = type
        planState.from = from
        planState.projectId = record.projectId
        planState.showChangeTitle = `预计变更记录 -${record.projectShortName}`
        planState.showChangeId = id
        planState.showChangeVisible = true
    }
    import { provide } from 'vue'
    function parentMethod() {
        planState.planChangeVisible = false
    }
    provide('parentMethod', parentMethod)
    function cancelPlanChange() {
        planState.planChangeVisible = false
    }
    function jumpWorkOrder(record) {
        const isLocal = window.location.host.includes('localhost')
        if (isLocal) {
            window.open(`${import.meta.env.VITE_PUBLIC_PATH}/page/xingongdan?factoryCode=${record.projectId}`, '_blank')
        } else {
            window.open(
                `${import.meta.env.VITE_PUBLIC_PATH}/allin-app/app_3000000079/page/3000001111?factoryCode=${
                    record.projectId
                }`,
                '_blank'
            )
        }
    }
    function jumpProject(record) {
        const isLocal = window.location.host.includes('localhost')
        if (isLocal) {
            window.open(`${import.meta.env.VITE_PUBLIC_PATH}/page/xinjiaofu?id=${record.projectId}`, '_blank')
        } else {
            window.open(`${import.meta.env.VITE_PUBLIC_PATH}/page/50001247?id=${record.projectId}`, '_blank')
        }
    }
    function cancelQuestion() {
        planState.questionVisible = false
        getData()
    }
    function cancelShowChange() {
        planState.showChangeVisible = false
    }
    // 端到端-计划调整
    const colorConfig = ref([])
    function getColorConfig() {
        post('/solution-ppm/api/v2/built-in-system-ppm/project_progress_delay_config/search', {
            'orderBy': 'id',
            'conditions': [
                {
                    'field': 'product_line',
                    'value': useTabName.value,
                    'operator': 'EQ',
                    'valueType': 'STRING'
                }
            ]
        }).then(data => {
            colorConfig.value = data.data
        })
    }
    const getBgcColor = text => {
        const match = colorConfig.value.find(item => Number(text) >= item.startDay && Number(text) <= item.endDay)
        if (match) {
            return { backgroundColor: match.displayColor }
        } else {
            return {} // 默认不设置背景色
        }
    }

    const progressState = reactive({
        visible: false,
        data: undefined,
        current: {}
    })
    function handleAddProgress(record) {
        progressState.current = record
        progressState.visible = true
    }
    function confirmProgress() {
        post('/solution-ppm/api/v2/built-in-system-ppm/project_progress/detail/create', {
            progressId: progressState.current.id,
            progress: progressState.data
        }).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            message.success(data.message)
            cancelProgress()
            getData()
        })
    }
    function cancelProgress() {
        progressState.current = {}
        progressState.visible = false
        progressState.data = undefined
    }
    // 判断是否禁用
    // function getDisabledState(time, stage) {
    //     const isPMO = currentData.value.edit === true
    //     const isProjectDirector = currentData.value.projectDirectorPermission === true
    //
    //     // PMO 可以编辑所有字段
    //     if (isPMO) return false
    //
    //     // 项目总监只可以编辑实际开始和实际结束
    //     if (isProjectDirector) {
    //         return !(time.field === 'actualStartTime' || time.field === 'actualEndTime')
    //     }
    //
    //     // 其他情况一律禁用
    //     return true
    // }
    function getDisabledState(time, stage) {
        const isPMO = currentData.value.edit === true
        const isPm = currentData.value.pmPermission === true
        const isProjectDirector = currentData.value.projectDirectorPermission === true

        // PMO 可以编辑所有字段
        if (isPMO) return false

        // 项目总监只可以编辑实际开始和实际结束
        if (isProjectDirector || isPm) {
            return !(time.field === 'actualStartTime' || time.field === 'actualEndTime')
        }

        // 其他情况一律禁用
        return true
    }

    // 时间维护
    function timeChange(time, stage) {
        if (time.label.includes('计划') || time.label.includes('实际')) {
            return
        }
        put(
            `/solution-ppm/api/v2/built-in-system-ppm/project_progress/modify/expect/${useTabName.value}`,
            state.changeForm.projectProgressStageList
        ).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                return
            }
            state.changeForm.projectProgressStageList = data.data
        })
    }
    const userInfoStorage = localStorage.getItem('al__USER_INFO')
    const taskLeader = JSON.parse(userInfoStorage)
    // const getDisabledStatus = (fieldType = 'normal') => {
    //     // 客情关系字段特殊处理（仅商务权限可编辑）
    //     if (fieldType === 'commercial') {
    //         return !currentData.value.commercialAffairs
    //     }
    //
    //     // 普通用户默认全部禁用
    //     const isNormalUser =
    //         !currentData.value.edit &&
    //         !currentData.value.projectDirectorPermission &&
    //         !currentData.value.commercialAffairs
    //     if (isNormalUser) return true
    //
    //     // 商务模式下，非商务字段全部禁用
    //     if (currentData.value.commercialAffairs) {
    //         return true
    //     }
    //
    //     // PMO和项目经理可编辑非商务字段
    //     return false
    // }
    const getDisabledStatus = (fieldType = 'normal') => {
        // 客情关系字段特殊处理（仅商务权限可编辑）
        if (fieldType === 'commercial') {
            return !currentData.value.commercialAffairs
        }

        // 将 pmPermission 与 projectDirectorPermission 保持一致
        const effectiveProjectDirectorPermission =
            currentData.value.projectDirectorPermission || currentData.value.pmPermission

        // 普通用户默认全部禁用
        const isNormalUser =
            !currentData.value.edit && !effectiveProjectDirectorPermission && !currentData.value.commercialAffairs
        if (isNormalUser) return true

        // 商务模式下，非商务字段全部禁用
        if (currentData.value.commercialAffairs) {
            return true
        }

        // PMO 和项目经理可编辑非商务字段
        return false
    }
    function isExpectOverdue(time, stage) {
        if (time.field !== 'expectEndTime') return false

        const expectTime = stage[time.field]
        const actualTime = stage.actualEndTime // 修正这里

        if (!expectTime || actualTime) return false

        return new Date(expectTime) < new Date()
    }

    //     判断进展
    function isToday(dateStr) {
        if (!dateStr) return false
        const date = new Date(dateStr)
        const now = new Date()

        return (
            date.getFullYear() === now.getFullYear() &&
            date.getMonth() === now.getMonth() &&
            date.getDate() === now.getDate()
        )
    }
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }
    /*样式*/
    .page_root {
        width: 100%;
        height: 100%;
        overflow: hidden;
        background-color: #f0f2f5;
    }
    .body {
        background-color: #f0f2f5;
        height: 100%;
    }
    .top-tab {
        height: 65px;
        padding: 16px 24px;
        background-color: #fff;
        margin-bottom: 16px;
        border-radius: 2px;
    }

    .time-div {
        display: flex;
        flex-direction: column;
        height: 65px;
    }
    .reality-time,
    .plan-time {
        height: 32px;
        width: 100%;
        text-align: center;
        line-height: 32px;
    }
    .plan-time {
        border-bottom: 1px solid #d9d9d9;
    }
    .kb-table-box {
        padding: 0 24px;
        padding-bottom: 24px;
        border-radius: 2px;
        background-color: #fff;
    }
    .kb-table-box:deep(.@{ant-prefix}-table-thead) > tr > th {
        background: #3875ff;
        color: #fff;
        font-weight: 600;
        padding: 0;
        border-right: 1px solid #d9d9d9 !important;
        position: relative;
    }
    .kb-table-box :deep(.@{ant-prefix}-table-tbody) tr > td {
        font-size: 14px;
        font-family: arial, helvetica, 'microsoft yahei';
        font-weight: 400;
        color: #262626;
        border-bottom: 1px solid #d9d9d9;
        padding: 0 5px;
        word-break: break-all;
    }

    .record-top,
    .record-bottom {
        display: flex;
        height: 32px;
    }
    .record-top {
        border-bottom: 1px solid #d9d9d9;
    }
    .extension,
    .normal,
    .planning {
        width: 25%;
        height: 32px;
        background-color: orange;
    }
    .normal {
        background-color: normal;
    }
    .planning {
        background-color: planning;
    }
    .table-tip {
        background-color: #fff;
        display: flex;
        height: 45px;
        justify-content: space-between;
        padding: 0 24px;
        align-items: center;
        position: relative;
    }

    .finish,
    .running,
    .daily {
        display: flex;
        line-height: 62px;
        margin-right: 13px;
    }

    .left-top {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 16px;
    }

    .right {
        flex: 1;
        display: flex;
        justify-content: end;
    }

    .tip-msg {
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 400;
    }

    .running-box {
        background: #aae56a;
    }

    .daily-box {
        background: #faba32;
    }
    .main {
        padding-top: 8px;
        background-color: #fff;
        height: 100%;
    }
    .color-father {
        width: 100px;
        display: flex;
        align-items: center;
        justify-content: space-between;
    }
    .no-margin {
        margin: 0;
    }
    .region-title {
        height: 26px;
        background: #fef0cc;
        border-radius: 2px;
        padding-left: 6px;
        font-size: 12px;
        color: #595959;
        line-height: 26px;
        font-weight: 400;
        margin-bottom: 16px;
    }
    .no-data-img {
        width: 264px;
        height: 192px;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    .no-data-msg {
        position: absolute;
        top: 60%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #595959;
    }
    .right-top {
        width: 70%;
        display: flex;
        align-items: center;
        justify-content: end;
        gap: 20px;
        color: #595959;
    }
    .tip-top-box {
        padding: 0 5px;
        border-radius: 2px;
        color: #fff;
        font-weight: 800;
    }
    .text-line-div {
        text-decoration: underline;
        position: relative;
    }

    .db-click {
        height: 30px;
        line-height: 30px;
        cursor: pointer;
    }
    .file-div {
        padding: 10px;
        width: 280px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        cursor: pointer;
    }
    .progress-click {
        height: 30px;
        line-height: 30px;
        cursor: pointer;
        display: flex;
    }
    :deep(.ant3-checkbox-wrapper + .ant3-checkbox-wrapper) {
        margin: 0;
    }
    .color-div {
        height: 40px;
        line-height: 40px;
    }
    .box {
        display: flex;
        width: 50%;
        height: 50%; /* 19px, 38px 的一半 */
        line-height: 20px;
        box-sizing: border-box; /* 包含 padding 和 border */
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 400;
    }
    .top-search {
        border-bottom: 1px solid #d9d9d9;
        padding: 16px 24px;
        background-color: #fff;
        padding-bottom: 10px;
    }
    .remark-content {
        padding: 10px 14px;
        border-radius: 5px;
        border: 1px solid #d9d9d9;
    }
    .remark-content p {
        margin-bottom: 0;
    }
    .tip1 {
        margin-left: 24px;
        display: flex;
        align-items: center;
    }
    .box1 {
        width: 32px;
        height: 8px;
        margin-left: 8px;
    }
    .tip-title {
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        line-height: 16px;
        padding-left: 8px;
        border-left: 4px solid #3875ff;
        height: 16px;
    }
    .title-font {
        font-size: 14px;
        color: #595959;
        letter-spacing: 0;
        text-align: center;
        font-weight: 400;
    }
    .marks-title {
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        margin-bottom: 8px;
    }
    .content-msg {
        width: 200px; /* 设置固定宽度 */
        word-wrap: break-word; /* 允许长单词换行 */
        overflow-wrap: break-word; /* 处理溢出 */
        white-space: normal; /* 正常换行 */
        flex-shrink: 0; /* 防止内容缩小 */
        text-align: left;
    }
    .toggle-icon {
        cursor: pointer; /* 鼠标指针样式 */
        color: #3875ff;
        position: relative;
        top: 1px;
        left: -6px;
        fontsize: 16px;
    }
    .icon-right {
        color: #3875ff;
        cursor: pointer;
    }
    .toggle-icon {
        fontsize: 16px;
    }
    .top-search :deep(.ant3-col-6) {
        height: 32px;
    }
    .kb-table-box :deep(.ant3-table-column-sorter-inner) {
        position: relative;
        left: -5px;
    }
    .omit-div,
    .omit-div-question,
    .omit-div-productionPlan,
    .omit-div-customerRelationship {
        width: 320px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        height: 100%;
        padding: 0 8px;
    }
    /* .question-div,
        .productionPlan-div,
        .kqjh-div {
            width: 320px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            height: 100%;
            padding: 0 8px;
            cursor: pointer;
            line-height: 35px;
        }
        */
    .question-div {
        position: relative;
        height: 20px;
    }

    .my-page :deep(.ant3-form-item-label) {
        width: 100px;
    }
    .form-content :deep(.ant3-form-item-label) {
        width: 120px;
    }
    .bottom-form :deep(.ant3-form-item-label) {
        width: 65px;
    }
    .modal-title {
        padding-left: 8px;
        border-left: 4px solid #3875ff;
        height: 16px;
        line-height: 16px;
        margin-top: 10px;
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        margin-bottom: 16px;
    }
    .col-height {
        height: 32px;
        margin-bottom: 16px;
    }
    .supportors {
        padding-right: 8px;
        width: 80px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .support-div {
        width: 120px;
        max-height: 100px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        cursor: pointer;
    }
    .top-num {
        height: 150px;
        background: #ffffff;
        border-radius: 4px;
        padding: 16px 24px;
        margin-bottom: 16px;
    }
    .num-content {
        display: flex;
        justify-content: space-between;
        gap: 16px;
        margin-top: 16px;
    }
    .num-item {
        flex: 1;
        display: flex;
        flex-direction: column;
        background: #ebf1ff;
        border: 1px solid #3875ff;
        border-radius: 4px;
        height: 80px;
        padding: 14px;
        text-align: center;
    }
    .total-num .num-bottom {
        font-size: 22px;
        color: #3875ff;
        letter-spacing: 0;
        font-weight: 500;
    }
    .num-bottom {
        font-size: 22px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 500;
    }
    .num-top {
        display: flex;
        gap: 4px;
        font-size: 14px;
        color: #595959;
        letter-spacing: 0;
        font-weight: 400;
        justify-content: center;
        align-items: center;
    }
    .ys-icon,
    .zzyx-icon,
    .yz-cion,
    .sys-icon,
    .jm-icon,
    .sjjm-icon {
        height: 16px;
        width: 16px;
    }
    .ys-icon {
        background-image: url('http://10.40.0.33:9001/file-storage/477573594104686592-source.png');
        background-size: cover;
    }
    .zzyx-icon {
        background-image: url('http://10.40.0.33:9001/file-storage/477573430939969536-source.png');
        background-size: cover;
    }
    .sys-icon {
        background-image: url('http://10.40.0.33:9001/file-storage/477573262773544960-source.png');
        background-size: cover;
    }
    .jm-icon {
        background-image: url('http://10.40.0.33:9001/file-storage/476874760477173760-source.png');
        background-size: cover;
    }
    .sjjm-icon {
        background-image: url('http://10.40.0.33:9001/file-storage/477573098140821504-source.png');
        background-size: cover;
    }
    .yz-cion {
        background-image: url('http://10.40.0.33:9001/file-storage/477573586028554240-source.png');
        background-size: cover;
    }
    .nums-top {
        font-size: 18px;
        color: #262626;
        letter-spacing: 0;
        line-height: 24px;
        font-weight: 500;
    }

    .del {
        width: 28px;
        color: #3875ff;
        position: absolute;
        right: 0;
        top: 5px;
    }

    .add-btn {
        position: absolute;
        right: 40px;
        color: #3875ff;
        top: 5px;
    }
    .my-page:deep(.ant3-picker) {
        width: 100%;
    }

    .form-content {
        display: inline-block;
        width: 100%;
    }
    .wt-item,
    .jz-item {
        position: relative;
    }
    .wt-item:last-child,
    .jz-item:last-child {
        border-bottom: none;
        margin-bottom: 0;
    }
    .jz-item {
        margin-bottom: 16px;
    }
    .bottom-title {
        display: flex;
        justify-content: space-between;
        align-items: start;
        margin-bottom: 16px;
    }
    .time-title {
        display: flex;
        justify-content: space-between;
        margin-bottom: 16px;
    }

    .jz-content {
        border-radius: 2px;
        background-color: #fff;
        padding: 5px 8px;
        border: 1px solid #d9d9d9;
    }
    .jz-body,
    .wt-body {
        background: #ecf2ff;
        border-radius: 4px;
        padding: 16px;
    }
    .wt-body {
        margin-bottom: 16px;
    }
    .jz-body {
        margin-bottom: 16px;
    }
    .jz-img,
    .wt-img {
        width: 16px;
        height: 16px;
    }
    .jz-img {
        background-image: url('http://10.40.0.33:9001/file-storage/477569053894338560-source.png');
        background-size: cover;
    }
    .wt-img {
        background-image: url('http://10.40.0.33:9001/file-storage/477569076266756096-source.png');
        background-size: cover;
    }
    .title-left {
        font-size: 16px;
        color: #3875ff;
        letter-spacing: 0;
        text-align: center;
        font-weight: 600;
        display: flex;
        align-items: center;
        gap: 2px;
    }
    .title-tip {
        display: flex;
        gap: 16px;
        margin-bottom: 8px;
        justify-content: flex-end;
    }
    .wt-title-tip {
        height: 36px;
        align-items: top;
        display: flex;
        gap: 16px;
        margin-bottom: 16px;
        border-bottom: 1px solid #3875ff;
    }
    .title-key {
        font-size: 14px;
        color: #595959;
        letter-spacing: 0;
        text-align: right;
        font-weight: 400;
    }
    .title-value {
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 400;
    }
    .draw-title {
        border-left: 4px solid #3875ff;
        padding-left: 8px;
        height: 16px;
        line-height: 16px;
    }
    .risk-level-tool-tip {
        margin: 0;
    }
    .statistics-div:deep(.ant3-form-item-label) {
        width: 120px;
    }
    .statisics-form-content {
        background: #f7f7f7;
        padding: 16px 24px;
        padding-left: 0;
    }
    .select-list {
        position: relative;
    }
    .form-content-select {
        width: calc(100% - 120px);
    }
    .select-btn {
        position: absolute;
        right: 16px;
        top: 0;
    }
    .select-btn :deep(.ant3-btn) {
        padding: 0;
    }
    .componment-item {
        margin-bottom: 16px;
    }
    .componment-item:last-child {
        margin-bottom: 0;
    }
    :deep(.ant3-table) {
        table-layout: auto; /* 这样表格列宽会自动调整 */
    }
    .top-classification {
        padding: 0 24px;
        display: flex;
        gap: 16px;
        justify-content: space-between;
        margin-top: 12px;
        margin-bottom: 16px;

        white-space: nowrap;
        flex-wrap: nowrap;
        overflow-x: auto;
    }
    .classification-item,
    .total-item {
        height: 48px;
        line-height: 48px;
        padding: 0 16px;
        position: relative;
        font-size: 14px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 400;
    }
    .classification-item {
        text-align: center;
        display: flex;
        align-items: center; /* 垂直居中对齐内容 */
        padding: 5px 10px; /* 内边距 */
        border-radius: 4px; /* 边框圆角 */
        box-sizing: border-box; /* 确保内边距不影响宽度计算 */
        flex-grow: 1; /* 允许元素伸展，占据可用空间 */
        //min-width: 150px; /* 设置最小宽度，避免元素过小 */
    }
    .total-num {
        width: 10%;
        background: #ebf1ff;
        border: 1px solid #3875ff;
        border-radius: 4px;
    }
    .other-num {
        flex: 1;
        display: flex;
        background: #ebf1ff;
        border: 1px solid #3875ff;
        border-radius: 4px;
        padding: 0 16px;
        gap: 16px; /* 设置子元素间的间距 */
        justify-content: space-between; /* 分配空余空间，使项均匀分布 */
        white-space: nowrap;
        flex-wrap: nowrap;
        overflow-x: auto;
    }
    .border-item {
        position: absolute;
        height: 36px;
        width: 1px;
        background-color: #3875ff;
        right: 0;
        top: 6px;
    }
    .plus-icon {
        position: absolute;
        right: 0;
        top: 0;
        cursor: pointer;
    }
    .meeting-div :deep(.ant3-form-item-label) {
        width: 130px;
    }
    .top-search :deep(.ant3-col) {
        height: 40px;
    }
    .active-icon {
        color: #3875ff;
        transform: rotate(90deg);
        margin-left: 8px;
    }
    .active-icon-down {
        color: #3875ff;
        transform: rotate(270deg);
        margin-left: 8px;
    }
    .toggle-content {
        cursor: pointer;
        color: #3875ff;
    }
    .tabs-content {
        background-color: #fff;
        padding: 0 16px;
    }
    .tabs-content :deep(.ant3-tabs-nav) {
        margin: 0;
    }
    .status-div {
        color: #fff;
        margin: 0 auto;
        border-radius: 4px;
        height: 20px;
        line-height: 20px;
    }
    .kb-table-box :deep(.ant3-table-cell-row-hover) {
        background-color: #d9d9d9 !important; /* 比默认加深一点 */
    }
    //.expect-overdue .ant3-picker {
    //    border: 1px solid red !important;
    //    box-shadow: 0 0 0 2px rgba(255, 0, 0, 0.2) !important;
    //}
    .expect-overdue :deep(.ant3-picker .ant3-picker-input > input) {
        color: red !important;
    }
</style>
